Index: head/sys/conf/files.arm64 =================================================================== --- head/sys/conf/files.arm64 (revision 353773) +++ head/sys/conf/files.arm64 (revision 353774) @@ -1,311 +1,314 @@ # $FreeBSD$ cloudabi32_vdso.o optional compat_cloudabi32 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_armv6_on_64bit.S" \ compile-with "${CC} -x assembler-with-cpp -m32 -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_armv6_on_64bit.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi32_vdso.o" # cloudabi32_vdso_blob.o optional compat_cloudabi32 \ dependency "cloudabi32_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-littleaarch64 --binary-architecture aarch64 cloudabi32_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi32_vdso_blob.o" # cloudabi64_vdso.o optional compat_cloudabi64 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_aarch64.S" \ compile-with "${CC} -x assembler-with-cpp -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_aarch64.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi64_vdso.o" # cloudabi64_vdso_blob.o optional compat_cloudabi64 \ dependency "cloudabi64_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-littleaarch64 --binary-architecture aarch64 cloudabi64_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi64_vdso_blob.o" # # Allwinner common files arm/allwinner/a10_timer.c optional a10_timer fdt arm/allwinner/a10_codec.c optional sound a10_codec arm/allwinner/a31_dmac.c optional a31_dmac arm/allwinner/sunxi_dma_if.m optional a31_dmac arm/allwinner/aw_cir.c optional evdev aw_cir fdt arm/allwinner/aw_dwc3.c optional aw_dwc3 fdt arm/allwinner/aw_gpio.c optional gpio aw_gpio fdt arm/allwinner/aw_mmc.c optional mmc aw_mmc fdt | mmccam aw_mmc fdt arm/allwinner/aw_nmi.c optional aw_nmi fdt \ compile-with "${NORMAL_C} -I$S/gnu/dts/include" arm/allwinner/aw_pwm.c optional aw_pwm fdt arm/allwinner/aw_rsb.c optional aw_rsb fdt arm/allwinner/aw_rtc.c optional aw_rtc fdt arm/allwinner/aw_sid.c optional aw_sid nvmem fdt arm/allwinner/aw_spi.c optional aw_spi fdt arm/allwinner/aw_syscon.c optional aw_syscon ext_resources syscon fdt arm/allwinner/aw_thermal.c optional aw_thermal nvmem fdt arm/allwinner/aw_usbphy.c optional ehci aw_usbphy fdt arm/allwinner/aw_usb3phy.c optional xhci aw_usbphy fdt arm/allwinner/aw_wdog.c optional aw_wdog fdt arm/allwinner/axp81x.c optional axp81x fdt arm/allwinner/if_awg.c optional awg ext_resources syscon aw_sid nvmem fdt # Allwinner clock driver arm/allwinner/clkng/aw_ccung.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_frac.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_m.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_mipi.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nkmp.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nm.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nmm.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_np.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_prediv_mux.c optional aw_ccu fdt arm/allwinner/clkng/ccu_a64.c optional soc_allwinner_a64 aw_ccu fdt arm/allwinner/clkng/ccu_h3.c optional soc_allwinner_h5 aw_ccu fdt arm/allwinner/clkng/ccu_h6.c optional soc_allwinner_h6 aw_ccu fdt arm/allwinner/clkng/ccu_h6_r.c optional soc_allwinner_h6 aw_ccu fdt arm/allwinner/clkng/ccu_sun8i_r.c optional aw_ccu fdt arm/allwinner/clkng/ccu_de2.c optional aw_ccu fdt # Allwinner padconf files arm/allwinner/a64/a64_padconf.c optional soc_allwinner_a64 fdt arm/allwinner/a64/a64_r_padconf.c optional soc_allwinner_a64 fdt arm/allwinner/h3/h3_padconf.c optional soc_allwinner_h5 fdt arm/allwinner/h3/h3_r_padconf.c optional soc_allwinner_h5 fdt arm/allwinner/h6/h6_padconf.c optional soc_allwinner_h6 fdt arm/allwinner/h6/h6_r_padconf.c optional soc_allwinner_h6 fdt arm/annapurna/alpine/alpine_ccu.c optional al_ccu fdt arm/annapurna/alpine/alpine_nb_service.c optional al_nb_service fdt arm/annapurna/alpine/alpine_pci.c optional al_pci fdt arm/annapurna/alpine/alpine_pci_msix.c optional al_pci fdt arm/annapurna/alpine/alpine_serdes.c optional al_serdes fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" arm/arm/generic_timer.c standard arm/arm/gic.c standard arm/arm/gic_acpi.c optional acpi arm/arm/gic_fdt.c optional fdt arm/arm/pmu.c standard arm/arm/physmem.c standard arm/broadcom/bcm2835/bcm2835_audio.c optional sound vchiq fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_cpufreq.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_dma.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_fbd.c optional vt soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_ft5406.c optional evdev bcm2835_ft5406 soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_gpio.c optional gpio soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_intr.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_mbox.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_rng.c optional !random_loadable soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_sdhost.c optional sdhci soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_vcio.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2835_wdog.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm2836.c optional soc_brcm_bcm2837 fdt arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt soc_brcm_bcm2837 arm/mv/a37x0_gpio.c optional a37x0_gpio gpio fdt arm/mv/armada38x/armada38x_rtc.c optional mv_rtc fdt arm/mv/gpio.c optional mv_gpio fdt arm/mv/mvebu_pinctrl.c optional mvebu_pinctrl fdt arm/mv/mv_ap806_clock.c optional SOC_MARVELL_8K fdt arm/mv/mv_ap806_gicp.c optional mv_ap806_gicp fdt arm/mv/mv_ap806_sei.c optional mv_ap806_sei fdt arm/mv/mv_cp110_clock.c optional SOC_MARVELL_8K fdt arm/mv/mv_cp110_icu.c optional mv_cp110_icu fdt arm/mv/mv_cp110_icu_bus.c optional mv_cp110_icu fdt arm/mv/mv_thermal.c optional SOC_MARVELL_8K mv_thermal fdt arm/mv/armada38x/armada38x_rtc.c optional mv_rtc fdt arm/xilinx/uart_dev_cdnc.c optional uart soc_xilinx_zynq arm64/acpica/acpi_iort.c optional acpi arm64/acpica/acpi_machdep.c optional acpi arm64/acpica/OsdEnvironment.c optional acpi arm64/acpica/acpi_wakeup.c optional acpi arm64/acpica/pci_cfgreg.c optional acpi pci arm64/arm64/autoconf.c standard arm64/arm64/bus_machdep.c standard arm64/arm64/bus_space_asm.S standard arm64/arm64/busdma_bounce.c standard arm64/arm64/busdma_machdep.c standard arm64/arm64/bzero.S standard arm64/arm64/clock.c standard arm64/arm64/copyinout.S standard arm64/arm64/copystr.c standard arm64/arm64/cpu_errata.c standard arm64/arm64/cpufunc_asm.S standard arm64/arm64/db_disasm.c optional ddb arm64/arm64/db_interface.c optional ddb arm64/arm64/db_trace.c optional ddb arm64/arm64/debug_monitor.c optional ddb arm64/arm64/disassem.c optional ddb arm64/arm64/dump_machdep.c standard arm64/arm64/efirt_machdep.c optional efirt arm64/arm64/elf32_machdep.c optional compat_freebsd32 arm64/arm64/elf_machdep.c standard arm64/arm64/exception.S standard arm64/arm64/freebsd32_machdep.c optional compat_freebsd32 arm64/arm64/gicv3_its.c optional intrng fdt arm64/arm64/gic_v3.c standard arm64/arm64/gic_v3_acpi.c optional acpi arm64/arm64/gic_v3_fdt.c optional fdt arm64/arm64/identcpu.c standard arm64/arm64/in_cksum.c optional inet | inet6 arm64/arm64/locore.S standard no-obj arm64/arm64/machdep.c standard arm64/arm64/mem.c standard arm64/arm64/memcpy.S standard arm64/arm64/memmove.S standard arm64/arm64/minidump_machdep.c standard arm64/arm64/mp_machdep.c optional smp arm64/arm64/nexus.c standard arm64/arm64/ofw_machdep.c optional fdt arm64/arm64/pmap.c standard arm64/arm64/stack_machdep.c optional ddb | stack arm64/arm64/support.S standard arm64/arm64/swtch.S standard arm64/arm64/sys_machdep.c standard arm64/arm64/trap.c standard arm64/arm64/uio_machdep.c standard arm64/arm64/uma_machdep.c standard arm64/arm64/undefined.c standard arm64/arm64/unwind.c optional ddb | kdtrace_hooks | stack arm64/arm64/vfp.c standard arm64/arm64/vm_machdep.c standard arm64/cavium/thunder_pcie_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_pem.c optional soc_cavm_thunderx pci arm64/cavium/thunder_pcie_pem_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_common.c optional soc_cavm_thunderx pci arm64/cloudabi32/cloudabi32_sysvec.c optional compat_cloudabi32 arm64/cloudabi64/cloudabi64_sysvec.c optional compat_cloudabi64 arm64/coresight/coresight.c standard arm64/coresight/coresight_if.m standard arm64/coresight/coresight-cmd.c standard arm64/coresight/coresight-cpu-debug.c standard arm64/coresight/coresight-dynamic-replicator.c standard arm64/coresight/coresight-etm4x.c standard arm64/coresight/coresight-funnel.c standard arm64/coresight/coresight-tmc.c standard arm64/intel/firmware.c optional soc_intel_stratix10 arm64/intel/stratix10-soc-fpga-mgr.c optional soc_intel_stratix10 arm64/intel/stratix10-svc.c optional soc_intel_stratix10 arm64/qualcomm/qcom_gcc.c optional qcom_gcc fdt contrib/vchiq/interface/compat/vchi_bsd.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_arm.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_connected.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_core.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_shim.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_util.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" crypto/armv8/armv8_crypto.c optional armv8crypto armv8_crypto_wrap.o optional armv8crypto \ dependency "$S/crypto/armv8/armv8_crypto_wrap.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc:N-mgeneral-regs-only} -I$S/crypto/armv8/ ${WERROR} ${NO_WCAST_QUAL} ${PROF} -march=armv8-a+crypto ${.IMPSRC}" \ no-implicit-rule \ clean "armv8_crypto_wrap.o" crypto/blowfish/bf_enc.c optional crypto | ipsec | ipsec_support crypto/des/des_enc.c optional crypto | ipsec | ipsec_support | netsmb dev/acpica/acpi_bus_if.m optional acpi dev/acpica/acpi_if.m optional acpi dev/acpica/acpi_pci_link.c optional acpi pci dev/acpica/acpi_pcib.c optional acpi pci dev/acpica/acpi_pxm.c optional acpi dev/ahci/ahci_generic.c optional ahci dev/altera/dwc/if_dwc_socfpga.c optional fdt dwc_socfpga dev/axgbe/if_axgbe.c optional axgbe dev/axgbe/xgbe-desc.c optional axgbe dev/axgbe/xgbe-dev.c optional axgbe dev/axgbe/xgbe-drv.c optional axgbe dev/axgbe/xgbe-mdio.c optional axgbe dev/cpufreq/cpufreq_dt.c optional cpufreq fdt dev/iicbus/sy8106a.c optional sy8106a fdt dev/iicbus/twsi/mv_twsi.c optional twsi fdt dev/iicbus/twsi/a10_twsi.c optional twsi fdt dev/iicbus/twsi/twsi.c optional twsi fdt dev/hwpmc/hwpmc_arm64.c optional hwpmc dev/hwpmc/hwpmc_arm64_md.c optional hwpmc dev/mbox/mbox_if.m optional soc_brcm_bcm2837 dev/mmc/host/dwmmc.c optional dwmmc fdt dev/mmc/host/dwmmc_altera.c optional dwmmc fdt dwmmc_altera dev/mmc/host/dwmmc_hisi.c optional dwmmc fdt soc_hisi_hi6220 dev/mmc/host/dwmmc_rockchip.c optional dwmmc fdt soc_rockchip_rk3328 dev/neta/if_mvneta_fdt.c optional neta fdt dev/neta/if_mvneta.c optional neta mdio mii dev/ofw/ofw_cpu.c optional fdt dev/ofw/ofwpci.c optional fdt pci dev/pci/pci_host_generic.c optional pci dev/pci/pci_host_generic_acpi.c optional pci acpi dev/pci/pci_host_generic_fdt.c optional pci fdt +dev/pci/pci_dw_mv.c optional pci fdt +dev/pci/pci_dw.c optional pci fdt +dev/pci/pci_dw_if.m optional pci fdt dev/psci/psci.c standard dev/psci/smccc_arm64.S standard dev/psci/smccc.c standard dev/sdhci/sdhci_xenon.c optional sdhci_xenon sdhci fdt dev/uart/uart_cpu_arm64.c optional uart dev/uart/uart_dev_mu.c optional uart uart_mu dev/uart/uart_dev_pl011.c optional uart pl011 dev/usb/controller/dwc_otg_hisi.c optional dwcotg fdt soc_hisi_hi6220 dev/usb/controller/dwc3.c optional fdt dwc3 dev/usb/controller/ehci_mv.c optional ehci_mv fdt dev/usb/controller/generic_ehci.c optional ehci dev/usb/controller/generic_ehci_acpi.c optional ehci acpi dev/usb/controller/generic_ehci_fdt.c optional ehci fdt dev/usb/controller/generic_ohci.c optional ohci fdt dev/usb/controller/generic_usb_if.m optional ohci fdt dev/usb/controller/usb_nop_xceiv.c optional fdt ext_resources dev/usb/controller/generic_xhci.c optional xhci dev/usb/controller/generic_xhci_acpi.c optional xhci acpi dev/usb/controller/generic_xhci_fdt.c optional xhci fdt dev/vnic/mrml_bridge.c optional vnic fdt dev/vnic/nic_main.c optional vnic pci dev/vnic/nicvf_main.c optional vnic pci pci_iov dev/vnic/nicvf_queues.c optional vnic pci pci_iov dev/vnic/thunder_bgx_fdt.c optional vnic fdt dev/vnic/thunder_bgx.c optional vnic pci dev/vnic/thunder_mdio_fdt.c optional vnic fdt dev/vnic/thunder_mdio.c optional vnic dev/vnic/lmac_if.m optional inet | inet6 | vnic kern/kern_clocksource.c standard kern/msi_if.m optional intrng kern/pic_if.m optional intrng kern/subr_devmap.c standard kern/subr_intr.c optional intrng libkern/bcmp.c standard libkern/memcmp.c standard libkern/memset.c standard libkern/arm64/crc32c_armv8.S standard cddl/dev/dtrace/aarch64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" cddl/dev/dtrace/aarch64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/aarch64/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" # RockChip Drivers arm64/rockchip/rk3399_emmcphy.c optional fdt rk_emmcphy soc_rockchip_rk3399 arm64/rockchip/rk_i2c.c optional fdt rk_i2c soc_rockchip_rk3328 | fdt rk_i2c soc_rockchip_rk3399 arm64/rockchip/rk805.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399 arm64/rockchip/rk_grf.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/rk_pinctrl.c optional fdt rk_pinctrl soc_rockchip_rk3328 | fdt rk_pinctrl soc_rockchip_rk3399 arm64/rockchip/rk_gpio.c optional fdt rk_gpio soc_rockchip_rk3328 | fdt rk_gpio soc_rockchip_rk3399 arm64/rockchip/rk_usb2phy.c optional fdt rk_usb2phy soc_rockchip_rk3328 | soc_rockchip_rk3399 arm64/rockchip/if_dwc_rk.c optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 dev/dwc/if_dwc.c optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 dev/dwc/if_dwc_if.m optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 # RockChip Clock support arm64/rockchip/clk/rk_cru.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_armclk.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_composite.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_gate.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_mux.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_pll.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk3328_cru.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk3399_cru.c optional fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk3399_pmucru.c optional fdt soc_rockchip_rk3399 Index: head/sys/dev/pci/pci_dw.c =================================================================== --- head/sys/dev/pci/pci_dw.c (nonexistent) +++ head/sys/dev/pci/pci_dw.c (revision 353774) @@ -0,0 +1,697 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019 Michal Meloun + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* Base class for all Synopsys DesignWare PCI/PCIe drivers */ + +#include +__FBSDID("$FreeBSD$"); + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcib_if.h" +#include "pci_dw_if.h" + +#define DEBUG +#ifdef DEBUG +#define debugf(fmt, args...) do { printf(fmt,##args); } while (0) +#else +#define debugf(fmt, args...) +#endif + +#define DBI_WR1(sc, reg, val) pci_dw_dbi_wr1((sc)->dev, reg, val) +#define DBI_WR2(sc, reg, val) pci_dw_dbi_wr2((sc)->dev, reg, val) +#define DBI_WR4(sc, reg, val) pci_dw_dbi_wr4((sc)->dev, reg, val) +#define DBI_RD1(sc, reg) pci_dw_dbi_rd1((sc)->dev, reg) +#define DBI_RD2(sc, reg) pci_dw_dbi_rd2((sc)->dev, reg) +#define DBI_RD4(sc, reg) pci_dw_dbi_rd4((sc)->dev, reg) + +#define PCI_BUS_SHIFT 20 +#define PCI_SLOT_SHIFT 15 +#define PCI_FUNC_SHIFT 12 +#define PCI_BUS_MASK 0xFF +#define PCI_SLOT_MASK 0x1F +#define PCI_FUNC_MASK 0x07 +#define PCI_REG_MASK 0xFFF + + +#define IATU_CFG_BUS(bus) ((uint64_t)((bus) & 0xff) << 24) +#define IATU_CFG_SLOT(slot) ((uint64_t)((slot) & 0x1f) << 19) +#define IATU_CFG_FUNC(func) ((uint64_t)((func) & 0x07) << 16) + + + +static uint32_t +pci_dw_dbi_read(device_t dev, u_int reg, int width) +{ + struct pci_dw_softc *sc; + + sc = device_get_softc(dev); + MPASS(sc->dbi_res != NULL); + + switch (width) { + case 4: + return (bus_read_4(sc->dbi_res, reg)); + case 2: + return (bus_read_2(sc->dbi_res, reg)); + case 1: + return (bus_read_1(sc->dbi_res, reg)); + default: + device_printf(sc->dev, "Unsupported width: %d\n", width); + return (0xFFFFFFFF); + } +} + +static void +pci_dw_dbi_write(device_t dev, u_int reg, uint32_t val, int width) +{ + struct pci_dw_softc *sc; + + sc = device_get_softc(dev); + MPASS(sc->dbi_res != NULL); + + switch (width) { + case 4: + bus_write_4(sc->dbi_res, reg, val); + break; + case 2: + bus_write_2(sc->dbi_res, reg, val); + break; + case 1: + bus_write_1(sc->dbi_res, reg, val); + break; + default: + device_printf(sc->dev, "Unsupported width: %d\n", width); + break; + } +} + + +static void +pci_dw_dbi_protect(struct pci_dw_softc *sc, bool protect) +{ + uint32_t reg; + + reg = DBI_RD4(sc, DW_MISC_CONTROL_1); + if (protect) + reg &= ~DBI_RO_WR_EN; + else + reg |= DBI_RO_WR_EN; + DBI_WR4(sc, DW_MISC_CONTROL_1, reg); +} + +static bool +pci_dw_check_dev(struct pci_dw_softc *sc, u_int bus, u_int slot, u_int func, + u_int reg) +{ + bool status; + int rv; + + if (bus < sc->bus_start || bus > sc->bus_end || slot > PCI_SLOTMAX || + func > PCI_FUNCMAX || reg > PCI_REGMAX) + return (false); + + /* link is needed for access to all non-root busses */ + if (bus != sc->root_bus) { + rv = PCI_DW_GET_LINK(sc->dev, &status); + if (rv != 0 || !status) + return (false); + return (true); + } + + /* we have only 1 device with 1 function root port */ + if (slot > 0 || func > 0) + return (false); + return (true); +} + +/* Map one uoutbound ATU region */ +static int +pci_dw_map_out_atu(struct pci_dw_softc *sc, int idx, int type, + uint64_t pa, uint64_t pci_addr, uint32_t size) +{ + uint32_t reg; + int i; + + if (size == 0) + return (0); + + DBI_WR4(sc, DW_IATU_VIEWPORT, IATU_REGION_INDEX(idx)); + DBI_WR4(sc, DW_IATU_LWR_BASE_ADDR, pa & 0xFFFFFFFF); + DBI_WR4(sc, DW_IATU_UPPER_BASE_ADDR, (pa >> 32) & 0xFFFFFFFF); + DBI_WR4(sc, DW_IATU_LIMIT_ADDR, (pa + size - 1) & 0xFFFFFFFF); + DBI_WR4(sc, DW_IATU_LWR_TARGET_ADDR, pci_addr & 0xFFFFFFFF); + DBI_WR4(sc, DW_IATU_UPPER_TARGET_ADDR, (pci_addr >> 32) & 0xFFFFFFFF); + DBI_WR4(sc, DW_IATU_CTRL1, IATU_CTRL1_TYPE(type)); + DBI_WR4(sc, DW_IATU_CTRL2, IATU_CTRL2_REGION_EN); + + /* Wait until setup becomes valid */ + for (i = 10; i > 0; i--) { + reg = DBI_RD4(sc, DW_IATU_CTRL2); + if (reg & IATU_CTRL2_REGION_EN) + return (0); + DELAY(5); + } + device_printf(sc->dev, + "Cannot map outbound region(%d) in iATU\n", idx); + return (ETIMEDOUT); +} + +static int +pci_dw_setup_hw(struct pci_dw_softc *sc) +{ + uint32_t reg; + int rv; + + pci_dw_dbi_protect(sc, false); + + /* Setup config registers */ + DBI_WR1(sc, PCIR_CLASS, PCIC_BRIDGE); + DBI_WR1(sc, PCIR_SUBCLASS, PCIS_BRIDGE_PCI); + DBI_WR4(sc, PCIR_BAR(0), 4); + DBI_WR4(sc, PCIR_BAR(1), 0); + DBI_WR1(sc, PCIR_INTPIN, 1); + DBI_WR1(sc, PCIR_PRIBUS_1, sc->root_bus); + DBI_WR1(sc, PCIR_SECBUS_1, sc->sub_bus); + DBI_WR1(sc, PCIR_SUBBUS_1, sc->bus_end); + DBI_WR2(sc, PCIR_COMMAND, + PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | + PCIM_CMD_BUSMASTEREN | PCIM_CMD_SERRESPEN); + pci_dw_dbi_protect(sc, true); + + /* Setup outbound memory window */ + rv = pci_dw_map_out_atu(sc, 0, IATU_CTRL1_TYPE_MEM, + sc->mem_range.host, sc->mem_range.pci, sc->mem_range.size); + if (rv != 0) + return (rv); + + /* If we have enouht viewports ..*/ + if (sc->num_viewport >= 3) { + /* Setup outbound I/O window */ + rv = pci_dw_map_out_atu(sc, 0, IATU_CTRL1_TYPE_MEM, + sc->io_range.host, sc->io_range.pci, sc->io_range.size); + if (rv != 0) + return (rv); + } + /* XXX Should we handle also prefetch memory? */ + + + /* Adjust number of lanes */ + reg = DBI_RD4(sc, DW_PORT_LINK_CTRL); + reg &= ~PORT_LINK_CAPABLE(~0); + switch (sc->num_lanes) { + case 1: + reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_1); + break; + case 2: + reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_2); + break; + case 4: + reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_4); + break; + case 8: + reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_8); + break; + case 16: + reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_16); + break; + case 32: + reg |= PORT_LINK_CAPABLE(PORT_LINK_CAPABLE_32); + break; + default: + device_printf(sc->dev, + "'num-lanes' property have invalid value: %d\n", + sc->num_lanes); + return (EINVAL); + } + DBI_WR4(sc, DW_PORT_LINK_CTRL, reg); + + + /* And link width */ + reg = DBI_RD4(sc, DW_GEN2_CTRL); + reg &= ~GEN2_CTRL_NUM_OF_LANES(~0); + switch (sc->num_lanes) { + case 1: + reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_1); + break; + case 2: + reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_2); + break; + case 4: + reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_4); + break; + case 8: + reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_8); + break; + case 16: + reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_16); + break; + case 32: + reg |= GEN2_CTRL_NUM_OF_LANES(GEN2_CTRL_NUM_OF_LANES_32); + break; + } + DBI_WR4(sc, DW_GEN2_CTRL, reg); + + reg = DBI_RD4(sc, DW_GEN2_CTRL); + reg |= DIRECT_SPEED_CHANGE; + DBI_WR4(sc, DW_GEN2_CTRL, reg); + + + return (0); +} + +static int +pci_dw_decode_ranges(struct pci_dw_softc *sc, struct ofw_pci_range *ranges, + int nranges) +{ + int i; + + for (i = 0; i < nranges; i++) { + if ((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == + OFW_PCI_PHYS_HI_SPACE_IO) { + if (sc->io_range.size != 0) { + device_printf(sc->dev, + "Duplicated IO range found in DT\n"); + return (ENXIO); + } + sc->io_range = ranges[i]; + } + if (((ranges[i].pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == + OFW_PCI_PHYS_HI_SPACE_MEM32)) { + if (ranges[i].pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) { + if (sc->pref_mem_range.size != 0) { + device_printf(sc->dev, + "Duplicated memory range found " + "in DT\n"); + return (ENXIO); + } + sc->pref_mem_range = ranges[i]; + } else { + if (sc->mem_range.size != 0) { + device_printf(sc->dev, + "Duplicated memory range found " + "in DT\n"); + return (ENXIO); + } + sc->mem_range = ranges[i]; + } + } + } + if ((sc->io_range.size == 0) || (sc->mem_range.size == 0)) { + device_printf(sc->dev, + " Not all required ranges are found in DT\n"); + return (ENXIO); + } + return (0); +} + + + +/*----------------------------------------------------------------------------- + * + * P C I B I N T E R F A C E + */ + +static uint32_t +pci_dw_read_config(device_t dev, u_int bus, u_int slot, + u_int func, u_int reg, int bytes) +{ + struct pci_dw_softc *sc; + struct resource *res; + uint32_t data; + uint64_t addr; + int type, rv; + + sc = device_get_softc(dev); + + if (!pci_dw_check_dev(sc, bus, slot, func, reg)) + return (0xFFFFFFFFU); + + if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) || + (reg > PCI_REGMAX)) + return (0xFFFFFFFFU); + + if (bus == sc->root_bus) { + res = (sc->dbi_res); + } else { + addr = IATU_CFG_BUS(bus) | IATU_CFG_SLOT(slot) | + IATU_CFG_FUNC(func); + if (bus == sc->sub_bus) + type = IATU_CTRL1_TYPE_CFG0; + else + type = IATU_CTRL1_TYPE_CFG1; + rv = pci_dw_map_out_atu(sc, 1, type, + sc->cfg_pa, addr, sc->cfg_size); + if (rv != 0) + return (0xFFFFFFFFU); + res = sc->cfg_res; + } + + switch (bytes) { + case 1: + data = bus_read_1(res, reg); + break; + case 2: + data = bus_read_2(res, reg); + break; + case 4: + data = bus_read_4(res, reg); + break; + default: + data = 0xFFFFFFFFU; + } + + return (data); + +} + +static void +pci_dw_write_config(device_t dev, u_int bus, u_int slot, + u_int func, u_int reg, uint32_t val, int bytes) +{ + struct pci_dw_softc *sc; + struct resource *res; + uint64_t addr; + int type, rv; + + sc = device_get_softc(dev); + if (!pci_dw_check_dev(sc, bus, slot, func, reg)) + return; + + if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) || + (reg > PCI_REGMAX)) + return; + + if (bus == sc->root_bus) { + res = (sc->dbi_res); + } else { + addr = IATU_CFG_BUS(bus) | IATU_CFG_SLOT(slot) | + IATU_CFG_FUNC(func); + if (bus == sc->sub_bus) + type = IATU_CTRL1_TYPE_CFG0; + else + type = IATU_CTRL1_TYPE_CFG1; + rv = pci_dw_map_out_atu(sc, 1, type, + sc->cfg_pa, addr, sc->cfg_size); + if (rv != 0) + return ; + res = sc->cfg_res; + } + + + switch (bytes) { + case 1: + bus_write_1(res, reg, val); + break; + case 2: + bus_write_2(res, reg, val); + break; + case 4: + bus_write_4(res, reg, val); + break; + default: + break; + } +} + +static int +pci_dw_alloc_msi(device_t pci, device_t child, int count, + int maxcount, int *irqs) +{ + phandle_t msi_parent; + int rv; + + rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), + &msi_parent, NULL); + if (rv != 0) + return (rv); + + return (intr_alloc_msi(pci, child, msi_parent, count, maxcount, + irqs)); +} + +static int +pci_dw_release_msi(device_t pci, device_t child, int count, int *irqs) +{ + phandle_t msi_parent; + int rv; + + rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), + &msi_parent, NULL); + if (rv != 0) + return (rv); + return (intr_release_msi(pci, child, msi_parent, count, irqs)); +} + +static int +pci_dw_map_msi(device_t pci, device_t child, int irq, uint64_t *addr, + uint32_t *data) +{ + phandle_t msi_parent; + int rv; + + rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), + &msi_parent, NULL); + if (rv != 0) + return (rv); + + return (intr_map_msi(pci, child, msi_parent, irq, addr, data)); +} + +static int +pci_dw_alloc_msix(device_t pci, device_t child, int *irq) +{ + phandle_t msi_parent; + int rv; + + rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), + &msi_parent, NULL); + if (rv != 0) + return (rv); + return (intr_alloc_msix(pci, child, msi_parent, irq)); +} + +static int +pci_dw_release_msix(device_t pci, device_t child, int irq) +{ + phandle_t msi_parent; + int rv; + + rv = ofw_bus_msimap(ofw_bus_get_node(pci), pci_get_rid(child), + &msi_parent, NULL); + if (rv != 0) + return (rv); + return (intr_release_msix(pci, child, msi_parent, irq)); +} + +static int +pci_dw_get_id(device_t pci, device_t child, enum pci_id_type type, + uintptr_t *id) +{ + phandle_t node; + int rv; + uint32_t rid; + uint16_t pci_rid; + + if (type != PCI_ID_MSI) + return (pcib_get_id(pci, child, type, id)); + + node = ofw_bus_get_node(pci); + pci_rid = pci_get_rid(child); + + rv = ofw_bus_msimap(node, pci_rid, NULL, &rid); + if (rv != 0) + return (rv); + *id = rid; + + return (0); +} + +/*----------------------------------------------------------------------------- + * + * B U S / D E V I C E I N T E R F A C E + */ +static bus_dma_tag_t +pci_dw_get_dma_tag(device_t dev, device_t child) +{ + struct pci_dw_softc *sc; + + sc = device_get_softc(dev); + return (sc->dmat); +} + +int +pci_dw_init(device_t dev) +{ + struct pci_dw_softc *sc; + int rv, rid; + + sc = device_get_softc(dev); + sc->dev = dev; + sc->node = ofw_bus_get_node(dev); + + mtx_init(&sc->mtx, "pci_dw_mtx", NULL, MTX_DEF); + + /* XXXn Should not be this configurable ? */ + sc->bus_start = 0; + sc->bus_end = 255; + sc->root_bus = 0; + sc->sub_bus = 1; + + /* Read FDT properties */ + if (!sc->coherent) + sc->coherent = OF_hasprop(sc->node, "dma-coherent"); + + rv = OF_getencprop(sc->node, "num-viewport", &sc->num_viewport, + sizeof(sc->num_viewport)); + if (rv != sizeof(sc->num_viewport)) + sc->num_viewport = 2; + + rv = OF_getencprop(sc->node, "num-lanes", &sc->num_lanes, + sizeof(sc->num_viewport)); + if (rv != sizeof(sc->num_lanes)) + sc->num_lanes = 1; + if (sc->num_lanes != 1 && sc->num_lanes != 2 && + sc->num_lanes != 4 && sc->num_lanes != 8) { + device_printf(dev, + "invalid number of lanes: %d\n",sc->num_lanes); + sc->num_lanes = 0; + rv = ENXIO; + goto out; + } + + rid = 0; + rv = ofw_bus_find_string_index(sc->node, "reg-names", "config", &rid); + if (rv != 0) { + device_printf(dev, "Cannot get config space memory\n"); + rv = ENXIO; + goto out; + } + sc->cfg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->cfg_res == NULL) { + device_printf(dev, "Cannot allocate config space(rid: %d)\n", + rid); + rv = ENXIO; + goto out; + } + + /* Fill up config region related variables */ + sc->cfg_size = rman_get_size(sc->cfg_res); + sc->cfg_pa = rman_get_start(sc->cfg_res) ; + + if (bootverbose) + device_printf(dev, "Bus is%s cache-coherent\n", + sc->coherent ? "" : " not"); + rv = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ + 1, 0, /* alignment, bounds */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + BUS_SPACE_MAXSIZE, /* maxsize */ + BUS_SPACE_UNRESTRICTED, /* nsegments */ + BUS_SPACE_MAXSIZE, /* maxsegsize */ + sc->coherent ? BUS_DMA_COHERENT : 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->dmat); + if (rv != 0) + goto out; + + rv = ofw_pci_init(dev); + if (rv != 0) + goto out; + rv = pci_dw_decode_ranges(sc, sc->ofw_pci.sc_range, + sc->ofw_pci.sc_nrange); + if (rv != 0) + goto out; + + rv = pci_dw_setup_hw(sc); + if (rv != 0) + goto out; + + device_add_child(dev, "pci", -1); + + return (bus_generic_attach(dev)); +out: + /* XXX Cleanup */ + return (rv); +} + +static device_method_t pci_dw_methods[] = { + + /* Bus interface */ + DEVMETHOD(bus_get_dma_tag, pci_dw_get_dma_tag), + + /* pcib interface */ + DEVMETHOD(pcib_read_config, pci_dw_read_config), + DEVMETHOD(pcib_write_config, pci_dw_write_config), + DEVMETHOD(pcib_alloc_msi, pci_dw_alloc_msi), + DEVMETHOD(pcib_release_msi, pci_dw_release_msi), + DEVMETHOD(pcib_alloc_msix, pci_dw_alloc_msix), + DEVMETHOD(pcib_release_msix, pci_dw_release_msix), + DEVMETHOD(pcib_map_msi, pci_dw_map_msi), + DEVMETHOD(pcib_get_id, pci_dw_get_id), + + /* OFW bus interface */ + DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), + DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), + DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), + DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), + DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), + + /* PCI DW interface */ + DEVMETHOD(pci_dw_dbi_read, pci_dw_dbi_read), + DEVMETHOD(pci_dw_dbi_write, pci_dw_dbi_write), + DEVMETHOD_END +}; + +DEFINE_CLASS_1(pcib, pci_dw_driver, pci_dw_methods, + sizeof(struct pci_dw_softc), ofw_pci_driver); Property changes on: head/sys/dev/pci/pci_dw.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/pci/pci_dw.h =================================================================== --- head/sys/dev/pci/pci_dw.h (nonexistent) +++ head/sys/dev/pci/pci_dw.h (revision 353774) @@ -0,0 +1,158 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019 Michal Meloun + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * $FreeBSD$ + * + */ + +#ifndef _PCI_DW_H_ +#define _PCI_DW_H_ + +#include "pci_dw_if.h" + + +/* DesignWare CIe configuration registers */ +#define DW_PORT_LINK_CTRL 0x710 +#define PORT_LINK_CAPABLE(n) (((n) & 0x3F) << 16) +#define PORT_LINK_CAPABLE_1 0x01 +#define PORT_LINK_CAPABLE_2 0x03 +#define PORT_LINK_CAPABLE_4 0x07 +#define PORT_LINK_CAPABLE_8 0x0F +#define PORT_LINK_CAPABLE_16 0x1F +#define PORT_LINK_CAPABLE_32 0x3F + + +#define DW_GEN2_CTRL 0x80C +#define DIRECT_SPEED_CHANGE (1 << 17) +#define GEN2_CTRL_NUM_OF_LANES(n) (((n) & 0x3F) << 8) +#define GEN2_CTRL_NUM_OF_LANES_1 0x01 +#define GEN2_CTRL_NUM_OF_LANES_2 0x03 +#define GEN2_CTRL_NUM_OF_LANES_4 0x07 +#define GEN2_CTRL_NUM_OF_LANES_8 0x0F +#define GEN2_CTRL_NUM_OF_LANES_16 0x1F +#define GEN2_CTRL_NUM_OF_LANES_32 0x3F + +#define DW_MSI_ADDR_LO 0x820 +#define DW_MSI_ADDR_HI 0x824 +#define DW_MSI_INTR0_ENABLE 0x828 +#define DW_MSI_INTR0_MASK 0x82C +#define DW_MSI_INTR0_STATUS 0x830 + + +#define DW_MISC_CONTROL_1 0x8BC +#define DBI_RO_WR_EN (1 << 0) + +#define DW_IATU_VIEWPORT 0x900 +#define IATU_REGION_INBOUND (1U << 31) +#define IATU_REGION_INDEX(x) ((x) & 0x7) +#define DW_IATU_CTRL1 0x904 +#define IATU_CTRL1_TYPE(x) ((x) & 0x1F) +#define IATU_CTRL1_TYPE_MEM 0x0 +#define IATU_CTRL1_TYPE_IO 0x2 +#define IATU_CTRL1_TYPE_CFG0 0x4 +#define IATU_CTRL1_TYPE_CFG1 0x5 +#define DW_IATU_CTRL2 0x908 +#define IATU_CTRL2_REGION_EN (1U << 31) +#define DW_IATU_LWR_BASE_ADDR 0x90C +#define DW_IATU_UPPER_BASE_ADDR 0x910 +#define DW_IATU_LIMIT_ADDR 0x914 +#define DW_IATU_LWR_TARGET_ADDR 0x918 +#define DW_IATU_UPPER_TARGET_ADDR 0x91C + + +struct pci_dw_softc { + struct ofw_pci_softc ofw_pci; /* Must be first */ + + /* Filled by attachement stub */ + struct resource *dbi_res; + + /* pci_dw variables */ + device_t dev; + phandle_t node; + struct mtx mtx; + struct resource *cfg_res; + + struct ofw_pci_range mem_range; + struct ofw_pci_range pref_mem_range; + struct ofw_pci_range io_range; + + bool coherent; + bus_dma_tag_t dmat; + + int num_lanes; + int num_viewport; + bus_addr_t cfg_pa; /* PA of config memoty */ + bus_size_t cfg_size; /* size of config region */ + + u_int bus_start; + u_int bus_end; + u_int root_bus; + u_int sub_bus; +}; + +DECLARE_CLASS(pci_dw_driver); + + +static inline void +pci_dw_dbi_wr4(device_t dev, u_int reg, uint32_t val) +{ + PCI_DW_DBI_WRITE(dev, reg, val, 4); +} + +static inline void +pci_dw_dbi_wr2(device_t dev, u_int reg, uint16_t val) +{ + PCI_DW_DBI_WRITE(dev, reg, val, 2); +} + +static inline void +pci_dw_dbi_wr1(device_t dev, u_int reg, uint8_t val) +{ + PCI_DW_DBI_WRITE(dev, reg, val, 1); +} + +static inline uint32_t +pci_dw_dbi_rd4(device_t dev, u_int reg) +{ + return (PCI_DW_DBI_READ(dev, reg, 4)); +} + +static inline uint16_t +pci_dw_dbi_rd2(device_t dev, u_int reg) +{ + return ((uint16_t)PCI_DW_DBI_READ(dev, reg, 2)); +} + +static inline uint8_t +pci_dw_dbi_rd1(device_t dev, u_int reg) +{ + return ((uint8_t)PCI_DW_DBI_READ(dev, reg, 1)); +} + +int pci_dw_init(device_t); + +#endif /* __PCI_HOST_GENERIC_H_ */ Property changes on: head/sys/dev/pci/pci_dw.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/pci/pci_dw_if.m =================================================================== --- head/sys/dev/pci/pci_dw_if.m (nonexistent) +++ head/sys/dev/pci/pci_dw_if.m (revision 353774) @@ -0,0 +1,73 @@ +#- +# Copyright (c) 2019 Michal Meloun +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +#include + +INTERFACE pci_dw; + + +/** + * Read from dbi space. + * The reg argument is a byte offset into dbi space. + * The width argument (which should be 1, 2 or 4) specifies how + * many bytes to read from that offset. + */ +METHOD uint32_t dbi_read{ + device_t dev; + u_int reg; + int width; +}; + +/** + * Write to dbi space. + * The reg argument is a byte offset into dbi space. + * The width argument (which should be 1, 2 or 4) specifies how + * many bytes to write to that offset. + */ +METHOD void dbi_write{ + device_t dev; + u_int reg; + uint32_t value; + int width; +}; + +/** + * Start or stop link + */ +METHOD int set_link{ + device_t dev; + bool start; +}; + +/** + * Query link status (up/down) + */ +METHOD int get_link{ + device_t dev; + bool *status; +}; Property changes on: head/sys/dev/pci/pci_dw_if.m ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/pci/pci_dw_mv.c =================================================================== --- head/sys/dev/pci/pci_dw_mv.c (nonexistent) +++ head/sys/dev/pci/pci_dw_mv.c (revision 353774) @@ -0,0 +1,328 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019 Michal Meloun + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* Armada 8k DesignWare PCIe driver */ + +#include +__FBSDID("$FreeBSD$"); + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcib_if.h" +#include "pci_dw_if.h" + +#define MV_GLOBAL_CONTROL_REG 0x8000 +#define PCIE_APP_LTSSM_EN (1 << 2) +//#define PCIE_DEVICE_TYPE_SHIFT 4 +//#define PCIE_DEVICE_TYPE_MASK 0xF +//#define PCIE_DEVICE_TYPE_RC 0x4/ + +#define MV_GLOBAL_STATUS_REG 0x8008 +#define MV_STATUS_RDLH_LINK_UP (1 << 1) +#define MV_STATUS_PHY_LINK_UP (1 << 9) + + +#define MV_INT_CAUSE1 0x801C +#define MV_INT_MASK1 0x8020 +#define INT_A_ASSERT_MASK (1 << 9) +#define INT_B_ASSERT_MASK (1 << 10) +#define INT_C_ASSERT_MASK (1 << 11) +#define INT_D_ASSERT_MASK (1 << 12) + +#define MV_INT_CAUSE2 0x8024 +#define MV_INT_MASK2 0x8028 +#define MV_ERR_INT_CAUSE 0x802C +#define MV_ERR_INT_MASK 0x8030 + +#define MV_ARCACHE_TRC_REG 0x8050 +#define MV_AWCACHE_TRC_REG 0x8054 +#define MV_ARUSER_REG 0x805C +#define MV_AWUSER_REG 0x8060 + + + +#define MV_MAX_LANES 8 + + +struct pci_mv_softc { + struct pci_dw_softc dw_sc; + device_t dev; + phandle_t node; + struct resource *irq_res; + void *intr_cookie; + phy_t phy[MV_MAX_LANES]; + clk_t clk_core; + clk_t clk_reg; +}; + +/* Compatible devices. */ +static struct ofw_compat_data compat_data[] = { + {"marvell,armada8k-pcie", 1}, + {NULL, 0}, +}; + + +static int +pci_mv_phy_init(struct pci_mv_softc *sc) +{ + int i, rv; + + for (i = 0; i < MV_MAX_LANES; i++) { + rv = phy_get_by_ofw_idx(sc->dev, sc->node, i, &(sc->phy[i])); + if (rv != 0 && rv != ENOENT) { + device_printf(sc->dev, "Cannot get phy[%d]\n", i); + goto fail; + } + if (sc->phy[i] == NULL) + continue; + rv = phy_enable(sc->phy[i]); + if (rv != 0) { + device_printf(sc->dev, "Cannot enable phy[%d]\n", i); + goto fail; + } + } + return (0); + +fail: + for (i = 0; i < MV_MAX_LANES; i++) { + if (sc->phy[i] == NULL) + continue; + phy_release(sc->phy[i]); + } + + return (rv); +} + +static void +pci_mv_init(struct pci_mv_softc *sc) +{ + uint32_t reg; + + + /* Set device configuration to RC */ + reg = pci_dw_dbi_rd4(sc->dev, MV_GLOBAL_CONTROL_REG); + reg &= ~0x000000F0; + reg |= 0x000000040; + pci_dw_dbi_wr4(sc->dev, MV_GLOBAL_CONTROL_REG, reg); + + /* AxCache master transaction attribures */ + pci_dw_dbi_wr4(sc->dev, MV_ARCACHE_TRC_REG, 0x3511); + pci_dw_dbi_wr4(sc->dev, MV_AWCACHE_TRC_REG, 0x5311); + + /* AxDomain master transaction attribures */ + pci_dw_dbi_wr4(sc->dev, MV_ARUSER_REG, 0x0002); + pci_dw_dbi_wr4(sc->dev, MV_AWUSER_REG, 0x0002); + + /* Enable all INTx interrupt (virtuual) pins */ + reg = pci_dw_dbi_rd4(sc->dev, MV_INT_MASK1); + reg |= INT_A_ASSERT_MASK | INT_B_ASSERT_MASK | + INT_C_ASSERT_MASK | INT_D_ASSERT_MASK; + pci_dw_dbi_wr4(sc->dev, MV_INT_MASK1, reg); + + /* Enable local interrupts */ + pci_dw_dbi_wr4(sc->dev, DW_MSI_INTR0_MASK, 0xFFFFFFFF); + pci_dw_dbi_wr4(sc->dev, MV_INT_MASK1, 0xFFFFFFFF); + pci_dw_dbi_wr4(sc->dev, MV_INT_MASK2, 0xFFFFFFFF); + pci_dw_dbi_wr4(sc->dev, MV_INT_CAUSE1, 0xFFFFFFFF); + pci_dw_dbi_wr4(sc->dev, MV_INT_CAUSE2, 0xFFFFFFFF); + + /* Errors have own interrupt, not yet populated in DTt */ + pci_dw_dbi_wr4(sc->dev, MV_ERR_INT_MASK, 0); +} +static int pci_mv_intr(void *arg) +{ + struct pci_mv_softc *sc = arg; + uint32_t cause1, cause2; + + /* Ack all interrups */ + cause1 = pci_dw_dbi_rd4(sc->dev, MV_INT_CAUSE1); + cause2 = pci_dw_dbi_rd4(sc->dev, MV_INT_CAUSE2); + if (cause1 == 0 || cause2 == 0) + return(FILTER_STRAY); + + pci_dw_dbi_wr4(sc->dev, MV_INT_CAUSE1, cause1); + pci_dw_dbi_wr4(sc->dev, MV_INT_CAUSE2, cause2); + return (FILTER_HANDLED); +} + +static int +pci_mv_get_link(device_t dev, bool *status) +{ + uint32_t reg; + + reg = pci_dw_dbi_rd4(dev, MV_GLOBAL_STATUS_REG); + if ((reg & (MV_STATUS_RDLH_LINK_UP | MV_STATUS_PHY_LINK_UP)) == + (MV_STATUS_RDLH_LINK_UP | MV_STATUS_PHY_LINK_UP)) + *status = true; + else + *status = false; + + return (0); +} + +static int +pci_mv_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); + + device_set_desc(dev, "Marvell Armada8K PCI-E Controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +pci_mv_attach(device_t dev) +{ + struct pci_mv_softc *sc; + phandle_t node; + int rv; + int rid; + + sc = device_get_softc(dev); + node = ofw_bus_get_node(dev); + sc->dev = dev; + sc->node = node; + + rid = 0; + sc->dw_sc.dbi_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->dw_sc.dbi_res == NULL) { + device_printf(dev, "Cannot allocate DBI memory\n"); + rv = ENXIO; + goto out; + } + + /* PCI interrupt */ + rid = 0; + sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE | RF_SHAREABLE); + if (sc->irq_res == NULL) { + device_printf(dev, "Cannot allocate IRQ resources\n"); + rv = ENXIO; + goto out; + } + + /* Clocks */ + rv = clk_get_by_ofw_name(sc->dev, 0, "core", &sc->clk_core); + if (rv != 0) { + device_printf(sc->dev, "Cannot get 'core' clock\n"); + rv = ENXIO; + goto out; + } + + rv = clk_get_by_ofw_name(sc->dev, 0, "reg", &sc->clk_reg); + if (rv != 0) { + device_printf(sc->dev, "Cannot get 'reg' clock\n"); + rv = ENXIO; + goto out; + } + + + rv = clk_enable(sc->clk_core); + if (rv != 0) { + device_printf(sc->dev, "Cannot enable 'core' clock\n"); + rv = ENXIO; + goto out; + } + + rv = clk_enable(sc->clk_reg); + if (rv != 0) { + device_printf(sc->dev, "Cannot enable 'reg' clock\n"); + rv = ENXIO; + goto out; + } + + rv = pci_mv_phy_init(sc); + if (rv) + goto out; + + rv = pci_dw_init(dev); + if (rv != 0) + goto out; + + pci_mv_init(sc); + + /* Setup interrupt */ + if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, + pci_mv_intr, NULL, sc, &sc->intr_cookie)) { + device_printf(dev, "cannot setup interrupt handler\n"); + rv = ENXIO; + goto out; + } + + return (bus_generic_attach(dev)); +out: + /* XXX Cleanup */ + return (rv); +} + +static device_method_t pci_mv_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, pci_mv_probe), + DEVMETHOD(device_attach, pci_mv_attach), + + DEVMETHOD(pci_dw_get_link, pci_mv_get_link), + + DEVMETHOD_END +}; + +DEFINE_CLASS_1(pcib, pci_mv_driver, pci_mv_methods, + sizeof(struct pci_mv_softc), pci_dw_driver); +static devclass_t pci_mv_devclass; +DRIVER_MODULE( pci_mv, simplebus, pci_mv_driver, pci_mv_devclass, + NULL, NULL); \ No newline at end of file Property changes on: head/sys/dev/pci/pci_dw_mv.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property