Pull up following revision(s) (requested by jmcneill in ticket #114):

sys/arch/arm/samsung/exynos_intr.h: revision 1.3
	sys/arch/arm/sunxi/sun8i_h3_ccu.c: revision 1.1
	sys/arch/arm/sunxi/sun8i_h3_ccu.c: revision 1.2
	sys/arch/arm/sunxi/sun8i_h3_ccu.c: revision 1.3
	sys/arch/arm/sunxi/sunxi_gates.c: revision 1.1
	distrib/utils/embedded/mkimage: revision 1.66
	sys/arch/arm/sunxi/sun8i_h3_ccu.c: revision 1.4
	sys/arch/arm/sunxi/sunxi_rsb.c: revision 1.1
	sys/arch/arm/sunxi/sun8i_h3_ccu.c: revision 1.5
	sys/arch/arm/sunxi/sun8i_h3_ccu.c: revision 1.6
	sys/arch/arm/sunxi/sun8i_h3_ccu.c: revision 1.7
	sys/dev/gpio/gpio.c: revision 1.59
	sys/arch/arm/sunxi/sunxi_ccu_prediv.c: revision 1.1
	sys/conf/Makefile.kern.inc: revision 1.257
	sys/arch/evbarm/conf/ODROID-XU_INSTALL: file removal
	sys/arch/arm/sunxi/sunxi_ccu_prediv.c: revision 1.2
	sys/conf/Makefile.kern.inc: revision 1.258
	sys/arch/arm/fdt/psci_fdt.h: revision 1.1
	sys/arch/arm/sunxi/sunxi_resets.c: revision 1.1
	sys/arch/evbarm/conf/files.sunxi: revision 1.1
	sys/arch/evbarm/fdt/fdt_machdep.c: revision 1.8
	sys/arch/evbarm/fdt/fdt_machdep.c: revision 1.9
	sys/arch/arm/samsung/files.exynos: revision 1.22
	distrib/utils/embedded/conf/armv7.conf: revision 1.13
	sys/arch/arm/samsung/files.exynos: revision 1.23
	sys/arch/evbarm/conf/std.tegra: revision 1.15
	distrib/utils/embedded/conf/armv7.conf: revision 1.14
	sys/arch/arm/samsung/files.exynos: revision 1.24
	distrib/utils/embedded/conf/armv7.conf: revision 1.15
	sys/arch/evbarm/sunxi/genassym.cf: revision 1.1
	sys/arch/arm/samsung/exynos_fdt.c: file removal
	sys/dev/fdt/fdt_pinctrl.c: revision 1.4
	sys/arch/arm/samsung/exynos_sysmmu.c: revision 1.2
	sys/arch/arm/sunxi/sun8i_h3_gpio.c: revision 1.1
	sys/arch/arm/sunxi/sunxi_twi.c: revision 1.1
	sys/dev/usb/ehci.c: revision 1.255
	sys/arch/arm/sunxi/sunxi_twi.c: revision 1.2
	sys/arch/arm/sunxi/sun8i_a83t_ccu.h: revision 1.1
	sys/dev/ic/dwc_mmc.c: revision 1.11
	sys/arch/arm/cortex/gic.c: revision 1.24
	distrib/evbarm/instkernel/ramdisk/Makefile: revision 1.17
	etc/etc.evbarm/Makefile.inc: revision 1.87
	etc/etc.evbarm/Makefile.inc: revision 1.88
	sys/arch/arm/fdt/gic_fdt.c: revision 1.5
	etc/Makefile: revision 1.429
	sys/arch/arm/fdt/gic_fdt.c: revision 1.6
	sys/arch/arm/fdt/gic_fdt.c: revision 1.7
	sys/arch/arm/sunxi/sunxi_gpio.c: revision 1.1
	sys/arch/arm/sunxi/sunxi_gpio.c: revision 1.2
	sys/arch/evbarm/conf/std.sunxi: revision 1.1
	sys/arch/arm/sunxi/sunxi_gpio.c: revision 1.3
	sys/arch/evbarm/conf/std.sunxi: revision 1.2
	sys/arch/arm/sunxi/sunxi_gpio.c: revision 1.4
	sys/arch/evbarm/conf/std.sunxi: revision 1.3
	sys/arch/arm/sunxi/sunxi_gpio.c: revision 1.5
	sys/arch/arm/sunxi/sunxi_ccu_div.c: revision 1.1
	sys/dev/gpio/gpiovar.h: revision 1.17
	sys/arch/arm/sunxi/sunxi_gpio.c: revision 1.6
	sys/arch/arm/sunxi/sunxi_gpio.c: revision 1.7
	sys/arch/arm/sunxi/sunxi_gpio.c: revision 1.8
	sys/arch/arm/sunxi/sunxi_rsb.h: revision 1.1
	sys/arch/arm/samsung/exynos_i2c.c: revision 1.12
	sys/dev/fdt/fdtvar.h: revision 1.21
	sys/arch/evbarm/sunxi/sunxi_start.S: revision 1.1
	sys/arch/arm/samsung/exynos_i2c.c: revision 1.13
	sys/dev/fdt/fdtvar.h: revision 1.22
	sys/arch/evbarm/conf/SUNXI: revision 1.10
	sys/dev/fdt/fdtvar.h: revision 1.23
	sys/arch/evbarm/conf/SUNXI: revision 1.11
	sys/dev/fdt/gpioleds.c: revision 1.1
	sys/dev/fdt/fdtvar.h: revision 1.24
	sys/arch/evbarm/conf/SUNXI: revision 1.12
	sys/arch/evbarm/conf/SUNXI: revision 1.13
	sys/arch/arm/cortex/gic.c: revision 1.30
	sys/arch/evbarm/conf/SUNXI: revision 1.14
	sys/arch/evbarm/conf/SUNXI: revision 1.15
	sys/arch/evbarm/conf/SUNXI: revision 1.16
	sys/arch/arm/sunxi/sunxi_emac.c: revision 1.1
	etc/Makefile: revision 1.430
	sys/arch/arm/sunxi/sunxi_emac.c: revision 1.2
	etc/Makefile: revision 1.431
	sys/arch/evbarm/conf/VEXPRESS_A15: revision 1.17
	sys/arch/arm/sunxi/sunxi_emac.c: revision 1.3
	sys/arch/arm/sunxi/sunxi_emac.c: revision 1.4
	sys/arch/arm/samsung/exynos5422_clock.c: revision 1.6
	sys/arch/arm/samsung/exynos_platform.c: revision 1.1
	sys/dev/ofw/ofw_subr.c: revision 1.29
	sys/arch/arm/samsung/exynos_platform.c: revision 1.2
	sys/arch/evbarm/conf/mk.vexpress: revision 1.3
	sys/arch/arm/samsung/exynos_platform.c: revision 1.3
	sys/arch/evbarm/conf/mk.vexpress: revision 1.4
	sys/arch/arm/samsung/exynos_platform.c: revision 1.4
	sys/arch/arm/arm/psci.h: revision 1.1
	sys/arch/arm/samsung/exynos_platform.c: revision 1.5
	sys/arch/arm/samsung/exynos_platform.c: revision 1.6
	sys/arch/evbarm/fdt/fdt_machdep.c: revision 1.10
	external/bsd/mdocml/bin/mandoc/Makefile: revision 1.12
	sys/dev/fdt/files.fdt: revision 1.17
	sys/dev/fdt/files.fdt: revision 1.18
	sys/dev/fdt/files.fdt: revision 1.19
	sys/arch/arm/samsung/exynos_sscom.c: revision 1.8
	sys/arch/arm/sunxi/sun8i_a83t_ccu.c: revision 1.1
	sys/arch/arm/sunxi/sunxi_mmc.c: revision 1.1
	sys/arch/arm/samsung/exynos_sscom.c: revision 1.9
	sys/arch/arm/conf/files.arm: revision 1.133
	sys/arch/arm/samsung/mct_var.h: revision 1.5
	sys/arch/arm/sunxi/sunxi_platform.c: revision 1.1
	sys/arch/arm/sunxi/sunxi_platform.c: revision 1.2
	sys/arch/evbarm/conf/std.vexpress: revision 1.6
	sys/arch/arm/sunxi/sunxi_platform.c: revision 1.3
	sys/arch/arm/sunxi/sun6i_a31_gpio.c: revision 1.1
	sys/arch/arm/sunxi/sunxi_platform.c: revision 1.4
	sys/arch/arm/sunxi/sun6i_a31_gpio.c: revision 1.2
	sys/arch/arm/sunxi/files.sunxi: revision 1.1
	sys/dev/ofw/ofw_subr.c: revision 1.30
	sys/arch/arm/sunxi/files.sunxi: revision 1.2
	sys/dev/ofw/openfirm.h: revision 1.35
	sys/arch/arm/sunxi/files.sunxi: revision 1.3
	sys/dev/ofw/openfirm.h: revision 1.36
	sys/arch/arm/sunxi/files.sunxi: revision 1.4
	sys/arch/arm/sunxi/files.sunxi: revision 1.5
	sys/arch/evbarm/exynos/exynos_machdep.c: file removal
	sys/arch/arm/sunxi/sunxi_gpio.h: revision 1.1
	sys/arch/arm/samsung/sscom.c: revision 1.9
	sys/arch/arm/sunxi/files.sunxi: revision 1.6
	sys/dev/fdt/ohci_fdt.c: revision 1.1
	sys/arch/arm/sunxi/sunxi_usbphy.c: revision 1.1
	sys/arch/arm/sunxi/sunxi_gpio.h: revision 1.2
	sys/arch/arm/sunxi/files.sunxi: revision 1.7
	sys/arch/arm/sunxi/sunxi_usbphy.c: revision 1.2
	sys/arch/arm/sunxi/sunxi_gpio.h: revision 1.3
	sys/arch/arm/sunxi/files.sunxi: revision 1.8
	sys/arch/arm/sunxi/sunxi_usbphy.c: revision 1.3
	sys/arch/arm/sunxi/files.sunxi: revision 1.9
	sys/arch/arm/samsung/exynos_sscom.c: revision 1.10
	sys/arch/evbarm/conf/mk.tegra: revision 1.5
	sys/arch/arm/samsung/exynos_dwcmmc.c: revision 1.4
	sys/arch/evbarm/conf/mk.tegra: revision 1.6
	sys/arch/evbarm/conf/EXYNOS: revision 1.15
	sys/arch/evbarm/conf/EXYNOS: revision 1.16
	sys/arch/evbarm/conf/EXYNOS: revision 1.17
	sys/arch/arm/sunxi/sunxi_ccu.c: revision 1.1
	sys/arch/evbarm/conf/EXYNOS: revision 1.19
	sys/arch/arm/sunxi/sunxi_ccu.c: revision 1.2
	sys/arch/arm/sunxi/sunxi_ccu.c: revision 1.3
	sys/arch/arm/sunxi/sunxi_ccu.c: revision 1.4
	sys/arch/arm/sunxi/sunxi_ccu.c: revision 1.5
	sys/arch/arm/sunxi/sunxi_emac.h: revision 1.1
	sys/arch/evbarm/conf/mk.sunxi: revision 1.1
	sys/arch/evbarm/include/bootconfig.h: revision 1.7
	sys/arch/evbarm/conf/TEGRA: revision 1.24
	sys/arch/arm/arm/psci.c: revision 1.1
	sys/dev/led.c: revision 1.1
	sys/dev/led.c: revision 1.2
	sys/arch/arm/arm/psci_arm.S: revision 1.1
	sys/arch/arm/sunxi/sunxi_ccu_gate.c: revision 1.1
	sys/arch/arm/sunxi/sunxi_ccu_gate.c: revision 1.2
	sys/dev/fdt/ehci_fdt.c: revision 1.1
	sys/dev/fdt/ehci_fdt.c: revision 1.2
	sys/arch/arm/sunxi/sun6i_a31_ccu.h: revision 1.1
	sys/arch/evbarm/conf/EXYNOS: revision 1.21
	sys/arch/arm/sunxi/files.sunxi: revision 1.10
	sys/arch/arm/sunxi/files.sunxi: revision 1.11
	sys/dev/fdt/fdtbus.c: revision 1.14
	sys/arch/arm/sunxi/sunxi_mmc.h: revision 1.1
	sys/arch/arm/samsung/exynos5422_dma.c: file removal
	usr.bin/config/mkmakefile.c: revision 1.69
	sys/conf/files: revision 1.1178
	sys/arch/arm/sunxi/sunxi_platform.h: revision 1.1
	sys/arch/evbarm/exynos/exynos_start.S: revision 1.4
	sys/arch/arm/samsung/exynos_pinctrl.c: revision 1.11
	sys/arch/arm/samsung/exynos_pinctrl.c: revision 1.12
	sys/arch/arm/sunxi/sunxi_rtc.c: revision 1.1
	sys/arch/arm/sunxi/sun8i_h3_ccu.h: revision 1.1
	sys/arch/arm/samsung/exynos5410_clock.c: revision 1.1
	sys/arch/arm/samsung/exynos5410_clock.c: revision 1.2
	sys/arch/evbarm/conf/SUNXI: revision 1.1
	external/bsd/elftosb/usr.sbin/elftosb/Makefile: revision 1.5
	sys/arch/evbarm/conf/SUNXI: revision 1.2
	sys/arch/arm/fdt/psci_fdt.c: revision 1.1
	sys/arch/evbarm/conf/SUNXI: revision 1.3
	sys/arch/evbarm/conf/SUNXI: revision 1.4
	sys/arch/evbarm/conf/files.exynos: revision 1.3
	sys/arch/evbarm/conf/SUNXI: revision 1.5
	sys/arch/evbarm/conf/SUNXI: revision 1.6
	sys/arch/arm/sunxi/sunxi_ccu_nm.c: revision 1.1
	sys/dev/fdt/fixedfactorclock.c: revision 1.1
	sys/dev/fdt/fdt_subr.c: revision 1.14
	sys/arch/evbarm/conf/SUNXI: revision 1.7
	sys/arch/arm/sunxi/sunxi_ccu_nm.c: revision 1.2
	sys/arch/arm/sunxi/sun8i_a83t_gpio.c: revision 1.1
	sys/dev/fdt/fdt_subr.c: revision 1.15
	sys/arch/evbarm/conf/SUNXI: revision 1.8
	sys/arch/arm/sunxi/sunxi_ccu_nm.c: revision 1.3
	sys/dev/ic/dwc_mmc_reg.h: revision 1.6
	sys/dev/fdt/fdt_subr.c: revision 1.16
	sys/arch/evbarm/conf/SUNXI: revision 1.9
	usr.bin/config/mkmakefile.c: revision 1.70
	sys/dev/fdt/fdt_phy.c: revision 1.1
	sys/arch/evbarm/conf/ODROID-XU: file removal
	sys/arch/arm/fdt/arm_fdt.c: revision 1.4
	sys/arch/arm/samsung/exynos_reg.h: revision 1.14
	sys/conf/files: revision 1.1180
	sys/arch/arm/samsung/exynos_reg.h: revision 1.15
	sys/arch/arm/sunxi/sunxi_ccu.h: revision 1.1
	sys/arch/arm/sunxi/sunxi_ccu.h: revision 1.2
	sys/arch/arm/sunxi/sunxi_ccu.h: revision 1.3
	sys/arch/arm/sunxi/sunxi_ccu.h: revision 1.4
	sys/arch/arm/sunxi/sunxi_ccu.h: revision 1.5
	sys/arch/arm/sunxi/sunxi_ccu.h: revision 1.6
	sys/dev/ic/dwc_mmc_var.h: revision 1.6
	sys/arch/arm/samsung/exynos_combiner.c: revision 1.7
	sys/arch/evbarm/exynos/platform.h: revision 1.2
	sys/arch/arm/fdt/files.fdt: revision 1.12
	sys/arch/evbarm/conf/std.exynos: revision 1.2
	sys/arch/evbarm/conf/std.exynos: revision 1.3
	sys/arch/arm/rockchip/rockchip_dwcmmc.c: revision 1.6
	sys/arch/arm/sunxi/sunxi_com.c: revision 1.1
	sys/dev/led.h: revision 1.1
	sys/arch/evbarm/conf/std.exynos: revision 1.5
	sys/arch/arm/sunxi/sunxi_com.c: revision 1.2
	sys/arch/evbarm/conf/files.evbarm: revision 1.26
	usr.bin/config/defs.h: revision 1.99
	sys/arch/arm/fdt/arm_fdtvar.h: revision 1.6
	sys/arch/arm/samsung/exynos_soc.c: revision 1.32
	sys/arch/arm/sunxi/sun6i_a31_ccu.c: revision 1.1
	sys/arch/arm/sunxi/sun6i_a31_ccu.c: revision 1.2
	sys/arch/arm/samsung/mct.c: revision 1.11
	sys/arch/evbarm/conf/ODROID-U: file removal
	sys/arch/arm/samsung/mct.c: revision 1.12
	sys/arch/arm/sunxi/sunxi_ccu_nkmp.c: revision 1.1
	sys/arch/arm/sunxi/sunxi_ccu_nkmp.c: revision 1.2
	sys/arch/arm/sunxi/sunxi_ccu_nkmp.c: revision 1.3
	sys/arch/arm/sunxi/sunxi_ccu_nkmp.c: revision 1.4
Get the EXYNOS kernel building again with recent FDT changes. Untested.
Use arm_fdt_cpu_hatch and add mmu entry for DTB
Fix exynos5 devmap, bootstrap, and implement early_putchar.
Calculate UART frequency based on bootloader config.
Fix KERNEL_BASE_PHYS (how did this ever work?)
Avoid divide-by-zero for unconfigured PLLs
Correctly initialize i2cbus attach args.
Add delay and enable mct timecounter.
Fix build w/o VERBOSE_INIT_ARM
Remove ODROID-U and ODROID-XU kernel configs as they no longer work.
- Replace CONSADDR with SSCOM2CONSOLE in example
- Remove gtmr (Exynos5422 uses mct)
- cinclude EXYNOS.local instead of TEGRA.local
Use fdtbus_intr_establish to hook in block interrupts instead of
intr_establish.
Simplify MCT; just enable it and then attach an ARMv7 generic timer.
Add support for building DTB files during kernel build, from christos.
build vexpress-v2p-ca15-tc1.dtb with the kernel
build tegra124-apalis-eval.dtb, tegra124-jetson-tk1.dtb, tegra124-nyan-big.dtb, tegra124-nyan-blaze.dtb, and tegra124-venice2.dtb with the kernel
Allow multiline makeoptions to work by quoting the newline..
Bump for quoting makeoptions with multiple lines.
un-c99
bump required config version for multiline makeoptions feature
Set DTS makeoption in kernel config
Assign DTB files to a variable so we can make -V DTB
put the dtb files with their kernels.
no need for debug printing.
Don't assume that CPU index = GIC CPU interface number. We can determine
the current CPU interface number by reading from the read-only
GICD_ITARGETSR0 through GICD_ITARGETSR7 registers.
This gets interrupts working on Exynos 5422, where the boot processor has
GIC CPU interface #4.
use -v to get the expanded variable.
Use -v to get the expanded variables.
Get baud rate from sclk_uartN instead of uartN. Print IRQ number at attach.
Fix PLL con0 register locations and add uart clocks
Disable exyortc for now, it doesn't work.
More or less a rewrite of dwc_mmc, based on awin_mmc, adding DMA support.
Update for new dwc_mmc driver
Fix dmesg
Add Exynos 5410 clock controller driver.
Fix a few typos in clock parent names for mmc clocks.
From jmcneill@
Update for new dwc_mmc driver
Implement platform reset for exynos5
Attach fdtbus to a /clocks node with no compatible string.
Add support for ARM Power State Coordination Interface (PSCI).
Support interrupt sharing.
Add initial support for Allwinner H3 SoC.
ARM Trusted Firmware reserves SGIs 8-15 for secure use. Even without ATF,
U-Boot on some platforms may use SGIs in this range for the PSCI
implementation.
Change ARMGIC_IPI_BASE to 0 from (16 - NIPI) and add a compile-time assert
to ensure that we don't end up with a conflict.
Add H3 MMC support
SD/MMC clock fixes
Add FDT PHY interface.
Add glue for generic ehci/ohci bindings.
Rename a variable, NFC.
Support parents in different clock domains.
Add USB stuff. Doesn't quite work yet.
Synopsys DesignWare APB UART needs "options COM_AWIN" for now.
Add i2c glue.
Add RTC driver.
PHY registers start at index 1. Now USB works.
Don't allow sharing edge and level triggered interrupts.
Add arm_fdt_memory_dump helper for dumping physical addresses from ddb
Print clocks with aprint_debug
Remove unused defines
Add fdtbus_get_string helper
Add of_search_compatible, which searches an array of compat_data structures
for a matching "compatible" entry matching the supplied OFW node. This
allows us to associate data with compatible strings.
Add driver for Allwinner Gigabit Ethernet (EMAC) as found in sun8i and
later family SoCs.
This is a port of my FreeBSD driver which has been confirmed to work on
Allwinner H3, A83T, and A64 SoCs.
Fix dmesg
Add basic support for Allwinner A31.
Add basic FDT GPIO support.
Fix the pinctrl api to match the spec. A pinctrl config can have more
than one xref, and an xref may have specifier data associated with it.
Enable sunxi pinctrl support
Adjust to new pinctrl API
Add P2WI/RSB driver, based on awin_p2wi.c.
Fix typo in a compat string.
Configure pin defaults at attach
No need to explicitly set pinctrl config 0 now
Fix some register definitions.
Disallow sharing between MPSAFE and non-MPSAFE handlers.
Add of_match_compat_data.
This routine searches an array of compat_data structures for a
matching "compatible" entry matching the supplied OFW node.
Add options __HAVE_CPU_UAREA_ALLOC_IDLELWP
Add support for reserved memory and MEMORY_DISK_DYNAMIC for FDT-based
kernels.
the extent code cannot use the full range of u_long,
so ignore the last page before 4GB too.  ok jmcneill@
Copy install ramdisk to releasedir. Provide both a raw ffs and
Legacy U-Boot version of it.
Replace HUMMINGBIRD_A31 with SUNXI kernel on armv7.img and include .dtb
files for SUNXI and TEGRA kernels on the MSDOS partition.
Let the controller provide a default name for pins. This makes pins easier
to locate when we have multiple banks and a variable number of pins per
bank.
Attach gpio(4) to sunxigpio
Test for kernel build directory before reading DTB list
Add support for Allwinner A83T SoC.
Add A83T files
Fixup busdma sync and locking in the RX path. Disable batch RX/TX ints.
Fix AHB2 register definition and explicitly set AHB2 parent to PLL_PERIPH0/2 -- this gives us 50% more bus bandwidth for emac
Restore TX_INTERVAL_DEFAULT to 64
Drop the sunxi_emac_rx_batch feature. It was originally designed to
reduce the amount of mutex unlock/lock cycles during the RX path on
FreeBSD and if_input, but it is not required to drop the lock before
calling if_percpuq_enqueue on NetBSD.
Write back the data value instead of mask in sunxi_gpio_write
Add a helper for exposing LED controls via sysctl.
Add GPIO LED driver.
add gpioleds
Add misc. gates and resets driver, and explicitly enable PIO clocks
at attach.
Add fdtbus_get_string_index helper.
Add driver for fixed-factor clocks.
Add ffclock
Remove the requirement for ehci to attach after companion devices.
"go for it" - skrll@
Remove the hack to find companion devices and just assume 1 companion if
ETTF flag is not set.
Remove pass numbers for ehci/ohci now that the attach order no longer matters
Use unsigned char for ctype functions, suggested by christos
Add : to body of populate_sunxi to appease bash.
port-evbarm/52388: Fix number of args to a debug printf.
This commit is contained in:
snj 2017-07-18 19:13:07 +00:00
parent 58286d5890
commit 5e6f0c1418
115 changed files with 13473 additions and 2584 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.16 2017/01/27 15:20:31 rin Exp $
# $NetBSD: Makefile,v 1.16.4.1 2017/07/18 19:13:07 snj Exp $
.include <bsd.own.mk>
.include "${NETBSDSRCDIR}/distrib/common/Makefile.distrib"
@ -38,6 +38,11 @@ ${CRUNCHBIN}: libhack.o
.include "${DISTRIBDIR}/common/Makefile.makedev"
.include "${DISTRIBDIR}/common/Makefile.image"
release:
release: ${IMAGE}
${RELEASE_INSTALL} ${IMAGE} \
${RELEASEDIR}/${RELEASEMACHINEDIR}/installation/ramdisk/
${TOOL_MKUBOOTIMAGE} -A arm -C none -O linux -T ramdisk \
-a 0 -n "NetBSD/${MACHINE_ARCH} ramdisk" ${IMAGE} \
${RELEASEDIR}/${RELEASEMACHINEDIR}/installation/ramdisk/${IMAGE:S/.fs/.ub/}
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
# $NetBSD: armv7.conf,v 1.12 2017/04/12 23:35:29 jmcneill Exp $
# $NetBSD: armv7.conf,v 1.12.4.1 2017/07/18 19:13:07 snj Exp $
# ARMv7 customization script used by mkimage
#
board=armv7
@ -8,10 +8,11 @@ resize=true
. ${DIR}/conf/evbarm.conf
kernels_beagle="BEAGLEBOARD BEAGLEBONE"
kernels_awin="BPI CUBIEBOARD CUBIETRUCK HUMMINGBIRD_A31"
kernels_awin="BPI CUBIEBOARD CUBIETRUCK"
kernels_rpi="RPI2"
kernels_amlogic="ODROID-C1"
kernels_tegra="TEGRA"
kernels_sunxi="SUNXI"
make_label() {
make_label_evbarm
@ -105,6 +106,10 @@ run bootcmd
EOF
}
populate_sunxi() {
:
}
populate_tegra() {
tegra_kernelimg=netbsd-TEGRA.ub
tegra_loadaddr=0x90000000
@ -124,7 +129,7 @@ populate() {
echo "${bar} looking for kernels in ${kernel} ${bar}"
kernels=""
# .ub kernels
for k in $kernels_beagle $kernels_awin $kernels_amlogic $kernels_tegra; do
for k in $kernels_beagle $kernels_awin $kernels_sunxi $kernels_amlogic $kernels_tegra; do
f="${kernel}/netbsd-${k}.ub.gz"
test -f "${f}" && kernels="${kernels} ${f}"
done
@ -133,6 +138,16 @@ populate() {
f="${kernel}/netbsd-${k}.bin.gz"
test -f "${f}" && kernels="${kernels} ${f}"
done
# .dtb files
for k in $kernels_sunxi $kernels_tegra; do
test -d "${KERNOBJDIR}/${k}" && \
dtbs="$(${MAKE} -C ${KERNOBJDIR}/${k} -v DTB)" || \
dtbs=
for dtb in $dtbs; do
f="${kernel}/${dtb}.gz"
test -f "${f}" && kernels="${kernels} ${f}"
done
done
# install kernels to /boot partition
for k in ${kernels}; do
@ -154,4 +169,5 @@ populate() {
populate_rpi
populate_amlogic
populate_tegra
populate_sunxi
}

View File

@ -1,5 +1,5 @@
#!/bin/sh
# $NetBSD: mkimage,v 1.64 2017/04/11 21:06:30 jmcneill Exp $
# $NetBSD: mkimage,v 1.64.4.1 2017/07/18 19:13:07 snj Exp $
#
# Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
# All rights reserved.
@ -51,6 +51,7 @@ set -e
DIR="$(cd "$(dirname "$0")" && pwd)"
PROG="$(basename "$0")"
MAKE=${TOOL_MAKE:-make}
DISKLABEL=${TOOL_DISKLABEL:-disklabel}
FDISK=${TOOL_FDISK:-fdisk}
MAKEFS=${TOOL_MAKEFS:-makefs}

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.428 2017/05/21 15:28:38 riastradh Exp $
# $NetBSD: Makefile,v 1.428.2.1 2017/07/18 19:13:07 snj Exp $
# from: @(#)Makefile 8.7 (Berkeley) 5/25/95
# Environment variables without default values:
@ -605,7 +605,7 @@ build_kernelsets: .PHONY
.if ${configfile} == ${configsel}
build_kernelsets: kernset-${configfile}
kernset-${configfile}: .PHONY build_kernels snap_pre
@ kernlist=$$(${GETKERNELAWK} ${KERNCONFDIR}/${configfile}); \
@kernlist=$$(${GETKERNELAWK} ${KERNCONFDIR}/${configfile}); \
kerndir=${KERNOBJDIR}/${configfile:C/.*\///}; \
kernsuffixes="${KERNEL_SUFFIXES:S/^/./}"; \
kern_tgz=${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/sets/kern-${configfile}.tgz; \
@ -625,6 +625,10 @@ kernset-${configfile}: .PHONY build_kernels snap_pre
echo "echo $${kernels} | $${pax_cmd}"; \
( echo "/set uname=${BINOWN} gname=${BINGRP}"; \
echo ". type=dir optional"; \
dtblist=$$(${MAKE} -v DTB); \
for dtb in $${dtblist}; do \
echo "./$${dtb} type=file"; \
done; \
for kernel in $${kernels}; do \
echo "./$${kernel} type=file"; \
done ) | eval $${pax_cmd}; \
@ -643,15 +647,25 @@ build_releasekernels: .PHONY
.if ${configfile} == ${configsel}
build_releasekernels: releasekern-${configfile}
releasekern-${configfile}: .PHONY build_kernels snap_pre
@ kernlist=$$(${GETKERNELAWK} ${KERNCONFDIR}/${configfile:C/.*\///}); \
@kernlist=$$(${GETKERNELAWK} ${KERNCONFDIR}/${configfile:C/.*\///}); \
kerndir=${KERNOBJDIR}/${configfile:C/.*\///}; \
kernsuffixes="${KERNEL_SUFFIXES:S/^/./}"; \
dest="${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/kernel"; \
cd $${kerndir} && { \
dtblist=$$(${MAKE} -v DTB); \
for dtb in $${dtblist}; do \
[ ! -f $${dtb} ] && continue; \
dtb_gz="$${dest}/$${dtb}.gz"; \
[ $${dtb_gz} -nt $${dtb} ] && continue; \
rm -f $${dtb_gz}; \
echo "${TOOL_GZIP} ${GZIP_FLAGS} -c < $${kerndir}/$${dtb} > $${dtb_gz}"; \
${TOOL_GZIP} ${GZIP_FLAGS} -c < $${dtb} > $${dtb_gz}; \
done; \
for kernel in $${kernlist}; do \
for s in "" $${kernsuffixes}; do \
ks="$${kernel}$${s}"; \
[ ! -f $${ks} ] && continue; \
knl_gz="${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/kernel/$${kernel}-${configfile:C/.*\///}$${s}.gz"; \
knl_gz="$${dest}/$${kernel}-${configfile:C/.*\///}$${s}.gz"; \
[ $${knl_gz} -nt $${ks} ] && continue; \
rm -f $${knl_gz}; \
echo "${TOOL_GZIP} ${GZIP_FLAGS} -c < $${kerndir}/$${ks} > $${knl_gz}"; \

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.81 2017/01/07 16:29:04 kiyohara Exp $
# $NetBSD: Makefile.inc,v 1.81.6.1 2017/07/18 19:13:08 snj Exp $
#
# etc.evbarm/Makefile.inc -- evbarm-specific etc Makefile targets
#
@ -134,6 +134,7 @@ IMAGE.kern= ${IMAGE.rel}/binary/kernel
IMAGE.instk= ${IMAGE.rel}/installation/instkernel
__mkimage: .USE
TOOL_MAKE=${MAKE} \
TOOL_MAKEFS=${TOOL_MAKEFS} \
TOOL_DISKLABEL=${TOOL_DISKLABEL} \
TOOL_FDISK=${TOOL_FDISK} \
@ -143,6 +144,8 @@ __mkimage: .USE
TOOL_MKUBOOTIMAGE=${TOOL_MKUBOOTIMAGE} \
TOOL_MTREE=${TOOL_MTREE} \
HOST_SH=${HOST_SH} \
KERNOBJDIR=${KERNOBJDIR} \
MACHINE=${MACHINE} \
${HOST_SH} ${MKIMAGE} -x -h ${.TARGET:S/smp_//} -D ${DESTDIR} \
-S ${NETBSDSRCDIR} -B ${IMAGEENDIAN} ${MKI_OPTS.${.TARGET}} \
${IMAGE.dir}/${.TARGET:S/smp_//}.img.gz
@ -197,4 +200,5 @@ snap_md_post: check_DESTDIR check_RELEASEDIR snap_post .WAIT ${SNAP_MD_POST_DEPS
KERNEL_SUFFIXES= bin srec ub
INSTALLATION_DIRS+= binary/gzimg \
installation/instkernel
installation/instkernel \
installation/ramdisk

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.4 2013/05/02 03:56:39 matt Exp $
# $NetBSD: Makefile,v 1.4.22.1 2017/07/18 19:13:08 snj Exp $
.include <bsd.init.mk>
.include <bsd.endian.mk>
@ -19,7 +19,7 @@ SRCS= BootImageGenerator.cpp \
elftosb_parser.tab.cpp
.ifdef HOSTPROG
SRCS.lib!=cd ${.PARSEDIR}/../../lib && ${MAKE} -V '$${SRCS}'
SRCS.lib!=cd ${.PARSEDIR}/../../lib && ${MAKE} -v SRCS
SRCS+=${SRCS.lib}
.endif

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.11 2016/07/15 19:40:42 christos Exp $
# $NetBSD: Makefile,v 1.11.6.1 2017/07/18 19:13:08 snj Exp $
.include <bsd.own.mk>
@ -15,7 +15,7 @@ DPADD+= ${MDOCMLLIB.mandoc} ${LIBZ}
LDADD+= -L${MDOCMLOBJDIR.mandoc} -lmandoc -lz
CPPFLAGS+= -DUSE_WCHAR
.else
SRCS.libmandoc!=cd ${.PARSEDIR}/../../lib/libmandoc && ${MAKE} -V '$${SRCS}'
SRCS.libmandoc!=cd ${.PARSEDIR}/../../lib/libmandoc && ${MAKE} -v SRCS
SRCS+= ${SRCS.libmandoc} compat_strtonum.c compat_reallocarray.c
.endif

120
sys/arch/arm/arm/psci.c Normal file
View File

@ -0,0 +1,120 @@
/* $NetBSD: psci.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include "opt_diagnostic.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: psci.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <arm/arm/psci.h>
/* PSCI methods */
#define PSCI_VERSION 0x84000000
#define PSCI_SYSTEM_OFF 0x84000008
#define PSCI_SYSTEM_RESET 0x84000009
#if defined(__aarch64__)
#define PSCI_CPU_ON 0xc4000002
#else
#define PSCI_CPU_ON 0x84000002
#endif
static psci_fn psci_call_fn;
static uint32_t psci_functions[PSCI_FUNC_MAX] = {
[PSCI_FUNC_VERSION] = PSCI_VERSION,
[PSCI_FUNC_SYSTEM_OFF] = PSCI_SYSTEM_OFF,
[PSCI_FUNC_SYSTEM_RESET] = PSCI_SYSTEM_RESET,
[PSCI_FUNC_CPU_ON] = PSCI_CPU_ON,
};
static int
psci_call(register_t fid, register_t arg1, register_t arg2, register_t arg3)
{
KASSERT(psci_call_fn != NULL);
if (fid == 0)
return PSCI_NOT_SUPPORTED;
return psci_call_fn(fid, arg1, arg2, arg3);
}
uint32_t
psci_version(void)
{
if (psci_functions[PSCI_FUNC_VERSION] == 0) {
/* Pre-0.2 implementation */
return __SHIFTIN(0, PSCI_VERSION_MAJOR) |
__SHIFTIN(1, PSCI_VERSION_MINOR);
}
return psci_call(psci_functions[PSCI_FUNC_VERSION], 0, 0, 0);
}
int
psci_cpu_on(register_t target_cpu, register_t entry_point_address,
register_t context_id)
{
return psci_call(psci_functions[PSCI_FUNC_CPU_ON], target_cpu,
entry_point_address, context_id);
}
void
psci_system_off(void)
{
psci_call(psci_functions[PSCI_FUNC_SYSTEM_OFF], 0, 0, 0);
}
void
psci_system_reset(void)
{
psci_call(psci_functions[PSCI_FUNC_SYSTEM_RESET], 0, 0, 0);
}
void
psci_init(psci_fn fn)
{
psci_call_fn = fn;
}
void
psci_clearfunc(void)
{
for (int i = 0; i < PSCI_FUNC_MAX; i++)
psci_setfunc(i, 0);
}
void
psci_setfunc(enum psci_function func, uint32_t fid)
{
psci_functions[func] = fid;
}

106
sys/arch/arm/arm/psci.h Normal file
View File

@ -0,0 +1,106 @@
/* $NetBSD: psci.h,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#ifndef _ARM_PSCI_H
#define _ARM_PSCI_H
/*
* List of supported PSCI functions.
*/
enum psci_function {
PSCI_FUNC_VERSION,
PSCI_FUNC_CPU_ON,
PSCI_FUNC_SYSTEM_OFF,
PSCI_FUNC_SYSTEM_RESET,
PSCI_FUNC_MAX
};
/*
* PSCI error codes
*/
#define PSCI_SUCCESS 0
#define PSCI_NOT_SUPPORTED -1
#define PSCI_INVALID_PARAMETERS -2
#define PSCI_DENIED -3
#define PSCI_ALREADY_ON -4
#define PSCI_ON_PENDING -5
#define PSCI_INTERNAL_FAILURE -6
#define PSCI_NOT_PRESENT -7
#define PSCI_DISABLED -8
#define PSCI_INVALID_ADDRESS -9
/*
* PSCI call method interface.
*/
typedef int (*psci_fn)(register_t, register_t, register_t, register_t);
/*
* Set the PSCI call method. Pass either psci_call_smc or psci_call_hvc.
*/
void psci_init(psci_fn);
/*
* PSCI call methods, implemented in psci.S
*/
int psci_call_smc(register_t, register_t, register_t, register_t);
int psci_call_hvc(register_t, register_t, register_t, register_t);
/*
* Clear PSCI function table. The default table includes function IDs for
* PSCI 0.2+. A PSCI 0.1 implementation will use its own function ID mappings.
*/
void psci_clearfunc(void);
/*
* Set PSCI function ID for a given PSCI function.
*/
void psci_setfunc(enum psci_function, uint32_t);
/*
* Return the version of PSCI implemented.
*/
uint32_t psci_version(void);
#define PSCI_VERSION_MAJOR __BITS(31,16)
#define PSCI_VERSION_MINOR __BITS(15,0)
/*
* Power up a core. Args: target_cpu, entry_point_address, context_id
*/
int psci_cpu_on(register_t, register_t, register_t);
/*
* Shut down the system.
*/
void psci_system_off(void);
/*
* Reset the system.
*/
void psci_system_reset(void);
#endif /* _ARM_PSCI_H */

View File

@ -0,0 +1,47 @@
/* $NetBSD: psci_arm.S,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <machine/asm.h>
RCSID("$NetBSD: psci_arm.S,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $");
.arch armv7a
.arch_extension sec
.arch_extension virt
/* Invoke PSCI function using Secure Monitor Call interface */
ENTRY(psci_call_smc)
smc #0
RET
END(psci_call_smc)
/* Invoke PSCI function using Hypervisor Call interface */
ENTRY(psci_call_hvc)
hvc #0
RET
END(psci_call_hvc)

View File

@ -1,4 +1,4 @@
# $NetBSD: files.arm,v 1.132 2017/05/26 21:17:46 jmcneill Exp $
# $NetBSD: files.arm,v 1.132.2.1 2017/07/18 19:13:08 snj Exp $
# temporary define to allow easy moving to ../arch/arm/arm32
defflag ARM32
@ -91,6 +91,11 @@ obsolete defflag ARMFPE
file arch/arm/vfp/vfp_init.c arm32
#file arch/arm/vfp/pmap_vfp.S arm32 & fpu_vfp
# Power State Coordination Interface (PSCI)
device psci
file arch/arm/arm/psci.c psci
file arch/arm/arm/psci_arm.S psci
# PMAP_DEBUG (heavily abused option)
defflag PMAP_DEBUG

View File

@ -1,4 +1,4 @@
/* $NetBSD: gic.c,v 1.21.2.1 2017/06/05 08:20:36 snj Exp $ */
/* $NetBSD: gic.c,v 1.21.2.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -34,7 +34,7 @@
#define _INTR_PRIVATE
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.21.2.1 2017/06/05 08:20:36 snj Exp $");
__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.21.2.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -53,7 +53,12 @@ __KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.21.2.1 2017/06/05 08:20:36 snj Exp $");
void armgic_irq_handler(void *);
#define ARMGIC_SGI_IPIBASE (16 - NIPI)
#define ARMGIC_SGI_IPIBASE 0
/*
* SGIs 8-16 are reserved for use by ARM Trusted Firmware.
*/
__CTASSERT(ARMGIC_SGI_IPIBASE + NIPI <= 8);
static int armgic_match(device_t, cfdata_t, void *);
static void armgic_attach(device_t, device_t, void *);
@ -100,6 +105,7 @@ static struct armgic_softc {
#ifdef MULTIPROCESSOR
uint32_t sc_mptargets;
#endif
uint32_t sc_bptargets;
} armgic_softc = {
.sc_pic = {
.pic_ops = &armgic_picops,
@ -139,6 +145,29 @@ gicd_write(struct armgic_softc *sc, bus_size_t o, uint32_t v)
bus_space_write_4(sc->sc_memt, sc->sc_gicdh, o, v);
}
static uint32_t
gicd_find_targets(struct armgic_softc *sc)
{
uint32_t targets = 0;
/*
* GICD_ITARGETSR0 through 7 are read-only, and each field returns
* a value that corresponds only to the processor reading the
* register. Use this to determine the current processor's
* CPU interface number.
*/
for (int i = 0; i < 8; i++) {
targets = gicd_read(sc, GICD_ITARGETSRn(i));
if (targets != 0)
break;
}
targets |= (targets >> 16);
targets |= (targets >> 8);
targets &= 0xff;
return targets ? targets : 1;
}
/*
* In the GIC prioritization scheme, lower numbers have higher priority.
* Only write priorities that could be non-secure.
@ -356,7 +385,7 @@ armgic_establish_irq(struct pic_softc *pic, struct intrsource *is)
} else
#endif
#endif
targets |= 1 << byte_shift;
targets |= sc->sc_bptargets << byte_shift;
gicd_write(sc, targets_reg, targets);
/*
@ -458,11 +487,11 @@ void
armgic_cpu_init(struct pic_softc *pic, struct cpu_info *ci)
{
struct armgic_softc * const sc = PICTOSOFTC(pic);
sc->sc_mptargets |= 1 << cpu_index(ci);
sc->sc_mptargets |= gicd_find_targets(sc);
KASSERTMSG(ci->ci_cpl == IPL_HIGH, "ipl %d not IPL_HIGH", ci->ci_cpl);
armgic_cpu_init_priorities(sc);
if (!CPU_IS_PRIMARY(ci)) {
if (sc->sc_mptargets != 1) {
if (popcount(sc->sc_mptargets) != 1) {
armgic_cpu_init_targets(sc);
}
if (sc->sc_enabled_local) {
@ -544,6 +573,11 @@ armgic_attach(device_t parent, device_t self, void *aux)
uint32_t pmr = gicc_read(sc, GICC_PMR);
u_int priorities = 1 << popcount32(pmr);
/*
* Find the boot processor's CPU interface number.
*/
sc->sc_bptargets = gicd_find_targets(sc);
/*
* Let's find out how many real sources we have.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: arm_fdt.c,v 1.3 2017/05/30 22:00:25 jmcneill Exp $ */
/* $NetBSD: arm_fdt.c,v 1.3.2.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared D. McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: arm_fdt.c,v 1.3 2017/05/30 22:00:25 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: arm_fdt.c,v 1.3.2.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -143,3 +143,26 @@ arm_fdt_irq_handler(void *tf)
{
_arm_fdt_irq_handler(tf);
}
void
arm_fdt_memory_dump(paddr_t pa)
{
const struct arm_platform *plat = arm_fdt_platform();
struct fdt_attach_args faa;
bus_space_tag_t bst;
bus_space_handle_t bsh;
plat->init_attach_args(&faa);
bst = faa.faa_bst;
bus_space_map(bst, pa, 0x100, 0, &bsh);
for (int i = 0; i < 0x100; i += 0x10) {
printf("%" PRIxPTR ": %08x %08x %08x %08x\n",
(uintptr_t)(pa + i),
bus_space_read_4(bst, bsh, i + 0),
bus_space_read_4(bst, bsh, i + 4),
bus_space_read_4(bst, bsh, i + 8),
bus_space_read_4(bst, bsh, i + 12));
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: arm_fdtvar.h,v 1.5 2017/06/02 13:53:28 jmcneill Exp $ */
/* $NetBSD: arm_fdtvar.h,v 1.5.2.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared D. McNeill <jmcneill@invisible.ca>
@ -71,4 +71,6 @@ void arm_fdt_cpu_hatch(struct cpu_info *);
void arm_fdt_irq_set_handler(void (*)(void *));
void arm_fdt_irq_handler(void *);
void arm_fdt_memory_dump(paddr_t);
#endif /* !_ARM_ARM_FDTVAR_H */

View File

@ -1,4 +1,4 @@
# $NetBSD: files.fdt,v 1.9.2.2 2017/06/10 05:57:08 snj Exp $
# $NetBSD: files.fdt,v 1.9.2.3 2017/07/18 19:13:08 snj Exp $
include "dev/pckbport/files.pckbport"
@ -38,5 +38,8 @@ file arch/arm/fdt/aaci_fdt.c aaci_fdt
attach plrtc at fdt with plrtc_fdt
file arch/arm/fdt/plrtc_fdt.c plrtc_fdt
attach psci at fdt with psci_fdt
file arch/arm/fdt/psci_fdt.c psci_fdt
# Console parameters
defparam opt_fdt_arm.h CONSADDR

View File

@ -1,4 +1,4 @@
/* $NetBSD: gic_fdt.c,v 1.4 2017/05/30 22:00:25 jmcneill Exp $ */
/* $NetBSD: gic_fdt.c,v 1.4.2.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gic_fdt.c,v 1.4 2017/05/30 22:00:25 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: gic_fdt.c,v 1.4.2.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -35,6 +35,7 @@ __KERNEL_RCSID(0, "$NetBSD: gic_fdt.c,v 1.4 2017/05/30 22:00:25 jmcneill Exp $")
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lwp.h>
#include <sys/kmem.h>
#include <arm/cortex/gic_intr.h>
@ -42,9 +43,13 @@ __KERNEL_RCSID(0, "$NetBSD: gic_fdt.c,v 1.4 2017/05/30 22:00:25 jmcneill Exp $")
#include <dev/fdt/fdtvar.h>
#define GIC_MAXIRQ 1020
static int gic_fdt_match(device_t, cfdata_t, void *);
static void gic_fdt_attach(device_t, device_t, void *);
static int gic_fdt_intr(void *);
static void * gic_fdt_establish(device_t, u_int *, int, int,
int (*)(void *), void *);
static void gic_fdt_disestablish(device_t, void *);
@ -56,9 +61,32 @@ struct fdtbus_interrupt_controller_func gic_fdt_funcs = {
.intrstr = gic_fdt_intrstr
};
struct gic_fdt_softc;
struct gic_fdt_irq;
struct gic_fdt_irqhandler {
struct gic_fdt_irq *ih_irq;
int (*ih_fn)(void *);
void *ih_arg;
bool ih_mpsafe;
TAILQ_ENTRY(gic_fdt_irqhandler) ih_next;
};
struct gic_fdt_irq {
struct gic_fdt_softc *intr_sc;
void *intr_ih;
int intr_refcnt;
int intr_ipl;
int intr_level;
int intr_mpsafe;
TAILQ_HEAD(, gic_fdt_irqhandler) intr_handlers;
};
struct gic_fdt_softc {
device_t sc_dev;
int sc_phandle;
struct gic_fdt_irq *sc_irq[GIC_MAXIRQ];
};
CFATTACH_DECL_NEW(gic_fdt, sizeof(struct gic_fdt_softc),
@ -137,7 +165,9 @@ static void *
gic_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags,
int (*func)(void *), void *arg)
{
int iflags = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0;
struct gic_fdt_softc * const sc = device_private(dev);
struct gic_fdt_irq *firq;
struct gic_fdt_irqhandler *firqh;
/* 1st cell is the interrupt type; 0 is SPI, 1 is PPI */
/* 2nd cell is the interrupt number */
@ -149,13 +179,80 @@ gic_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags,
const u_int trig = be32toh(specifier[2]) & 0xf;
const u_int level = (trig & 0x3) ? IST_EDGE : IST_LEVEL;
return intr_establish(irq, ipl, level | iflags, func, arg);
const u_int mpsafe = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0;
firq = sc->sc_irq[irq];
if (firq == NULL) {
firq = kmem_alloc(sizeof(*firq), KM_SLEEP);
firq->intr_sc = sc;
firq->intr_refcnt = 0;
firq->intr_ipl = ipl;
firq->intr_level = level;
firq->intr_mpsafe = mpsafe;
TAILQ_INIT(&firq->intr_handlers);
firq->intr_ih = intr_establish(irq, ipl, level | mpsafe,
gic_fdt_intr, firq);
if (firq->intr_ih == NULL) {
kmem_free(firq, sizeof(*firq));
return NULL;
}
sc->sc_irq[irq] = firq;
}
if (firq->intr_ipl != ipl) {
device_printf(dev, "cannot share irq with different ipl\n");
return NULL;
}
if (firq->intr_level != level) {
device_printf(dev, "cannot share edge and level interrupts\n");
return NULL;
}
if (firq->intr_mpsafe != mpsafe) {
device_printf(dev, "cannot share between mpsafe/non-mpsafe\n");
return NULL;
}
firq->intr_refcnt++;
firqh = kmem_alloc(sizeof(*firqh), KM_SLEEP);
firqh->ih_mpsafe = (flags & FDT_INTR_MPSAFE) != 0;
firqh->ih_irq = firq;
firqh->ih_fn = func;
firqh->ih_arg = arg;
TAILQ_INSERT_TAIL(&firq->intr_handlers, firqh, ih_next);
return firqh;
}
static void
gic_fdt_disestablish(device_t dev, void *ih)
{
intr_disestablish(ih);
struct gic_fdt_irqhandler *firqh = ih;
struct gic_fdt_irq *firq = firqh->ih_irq;
KASSERT(firq->intr_refcnt > 0);
TAILQ_REMOVE(&firq->intr_handlers, firqh, ih_next);
kmem_free(firqh, sizeof(*firqh));
firq->intr_refcnt--;
if (firq->intr_refcnt == 0) {
intr_disestablish(firq->intr_ih);
kmem_free(firq, sizeof(*firq));
}
}
static int
gic_fdt_intr(void *priv)
{
struct gic_fdt_irq *firq = priv;
struct gic_fdt_irqhandler *firqh;
int handled = 0;
TAILQ_FOREACH(firqh, &firq->intr_handlers, ih_next)
handled += firqh->ih_fn(firqh->ih_arg);
return handled;
}
static bool

176
sys/arch/arm/fdt/psci_fdt.c Normal file
View File

@ -0,0 +1,176 @@
/* $NetBSD: psci_fdt.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: psci_fdt.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <dev/fdt/fdtvar.h>
#include <arm/locore.h>
#include <arm/armreg.h>
#include <arm/arm/psci.h>
#include <arm/fdt/psci_fdt.h>
static int psci_fdt_match(device_t, cfdata_t, void *);
static void psci_fdt_attach(device_t, device_t, void *);
static int psci_fdt_init(const int);
static const char * const compatible[] = {
"arm,psci",
"arm,psci-0.2",
"arm,psci-1.0",
NULL
};
CFATTACH_DECL_NEW(psci_fdt, 0, psci_fdt_match, psci_fdt_attach, NULL, NULL);
static int
psci_fdt_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
psci_fdt_attach(device_t parent, device_t self, void *aux)
{
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
psci_fdt_init(phandle);
const uint32_t ver = psci_version();
const u_int ver_maj = __SHIFTOUT(ver, PSCI_VERSION_MAJOR);
const u_int ver_min = __SHIFTOUT(ver, PSCI_VERSION_MINOR);
aprint_naive("\n");
aprint_normal(": PSCI %u.%u\n", ver_maj, ver_min);
}
static int
psci_fdt_init(const int phandle)
{
char method[4];
uint32_t val;
if (!of_hasprop(phandle, "method")) {
aprint_error("PSCI: missing 'method' property\n");
return EINVAL;
}
OF_getprop(phandle, "method", method, sizeof(method));
if (strcmp(method, "smc") == 0)
psci_init(psci_call_smc);
else if (strcmp(method, "hvc") == 0)
psci_init(psci_call_hvc);
else {
aprint_error("PSCI: unsupported method '%s'\n", method);
return EINVAL;
}
const char * const compat_0_1[] = { "arm,psci", NULL };
if (of_match_compatible(phandle, compat_0_1)) {
psci_clearfunc();
if (of_getprop_uint32(phandle, "cpu_on", &val) == 0)
psci_setfunc(PSCI_FUNC_CPU_ON, val);
}
return 0;
}
void
psci_fdt_bootstrap(void)
{
extern void cortex_mpstart(void);
bus_addr_t mpidr;
uint32_t bp_mpidr;
int child;
const int cpus = OF_finddevice("/cpus");
if (cpus == -1) {
aprint_error("PSCI: no /cpus node found\n");
arm_cpu_max = 1;
return;
}
/* Count CPUs */
arm_cpu_max = 0;
for (child = OF_child(cpus); child; child = OF_peer(child))
if (fdtbus_status_okay(child))
arm_cpu_max++;
const int phandle = OF_finddevice("/psci");
if (phandle == -1) {
aprint_error("PSCI: no /psci node found\n");
return;
}
if (psci_fdt_init(phandle) != 0)
return;
/* MPIDR affinity levels of boot processor. */
bp_mpidr = armreg_mpidr_read() & (MPIDR_AFF2|MPIDR_AFF1|MPIDR_AFF0);
/* Boot APs */
uint32_t started = 0;
for (child = OF_child(cpus); child; child = OF_peer(child)) {
if (!fdtbus_status_okay(child))
continue;
if (fdtbus_get_reg(child, 0, &mpidr, NULL) != 0)
continue;
if (mpidr == bp_mpidr)
continue; /* BP already started */
/* XXX NetBSD requires all CPUs to be in the same cluster */
const u_int bp_clid = __SHIFTOUT(bp_mpidr, CORTEXA9_MPIDR_CLID);
const u_int clid = __SHIFTOUT(mpidr, CORTEXA9_MPIDR_CLID);
if (bp_clid != clid)
continue;
const u_int cpuid = __SHIFTOUT(mpidr, CORTEXA9_MPIDR_CPUID);
int ret = psci_cpu_on(cpuid, (register_t)cortex_mpstart, 0);
if (ret == PSCI_SUCCESS)
started |= __BIT(cpuid);
}
/* Wait for APs to start */
for (u_int i = 0x10000000; i > 0; i--) {
arm_dmb();
if (arm_cpu_hatched == started)
break;
}
}

View File

@ -0,0 +1,35 @@
/* $NetBSD: psci_fdt.h,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#ifndef _ARM_PSCI_FDT_H
#define _ARM_PSCI_FDT_H
/* Initialize PSCI and boot APs */
void psci_fdt_bootstrap(void);
#endif /* !_ARM_PSCI_FDT_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: rockchip_dwcmmc.c,v 1.5 2015/01/03 13:29:02 jmcneill Exp $ */
/* $NetBSD: rockchip_dwcmmc.c,v 1.5.12.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rockchip_dwcmmc.c,v 1.5 2015/01/03 13:29:02 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: rockchip_dwcmmc.c,v 1.5.12.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -46,8 +46,6 @@ __KERNEL_RCSID(0, "$NetBSD: rockchip_dwcmmc.c,v 1.5 2015/01/03 13:29:02 jmcneill
static int rk_dwcmmc_match(device_t, cfdata_t, void *);
static void rk_dwcmmc_attach(device_t, device_t, void *);
static void rk_dwcmmc_attach_i(device_t);
CFATTACH_DECL_NEW(rkdwcmmc, sizeof(struct dwc_mmc_softc),
rk_dwcmmc_match, rk_dwcmmc_attach, NULL, NULL);
@ -68,8 +66,7 @@ rk_dwcmmc_attach(device_t parent, device_t self, void *aux)
sc->sc_dev = self;
sc->sc_bst = obio->obio_bst;
sc->sc_dmat = obio->obio_dmat;
sc->sc_flags = DWC_MMC_F_USE_HOLD_REG | DWC_MMC_F_PWREN_CLEAR |
DWC_MMC_F_FORCE_CLK;
sc->sc_flags = DWC_MMC_F_USE_HOLD_REG;
sc->sc_clock_freq = rockchip_mmc0_get_rate();
#if 0
sc->sc_clock_max = 24000;
@ -82,6 +79,9 @@ rk_dwcmmc_attach(device_t parent, device_t self, void *aux)
aprint_naive("\n");
aprint_normal(": SD/MMC controller\n");
if (dwc_mmc_init(sc) != 0)
return;
sc->sc_ih = intr_establish(obio->obio_intr, IPL_BIO, IST_LEVEL,
dwc_mmc_intr, sc);
if (sc->sc_ih == NULL) {
@ -89,14 +89,4 @@ rk_dwcmmc_attach(device_t parent, device_t self, void *aux)
obio->obio_intr);
return;
}
config_interrupts(self, rk_dwcmmc_attach_i);
}
static void
rk_dwcmmc_attach_i(device_t self)
{
struct dwc_mmc_softc *sc = device_private(self);
dwc_mmc_init(sc);
}

View File

@ -0,0 +1,864 @@
/* $NetBSD: exynos5410_clock.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exynos5410_clock.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/atomic.h>
#include <dev/clk/clk_backend.h>
#include <arm/samsung/exynos_reg.h>
#include <arm/samsung/exynos_var.h>
#include <arm/samsung/exynos_clock.h>
#include <dev/fdt/fdtvar.h>
static struct clk *exynos5410_clock_decode(device_t, const void *, size_t);
static const struct fdtbus_clock_controller_func exynos5410_car_fdtclock_funcs = {
.decode = exynos5410_clock_decode
};
/* DT clock ID to clock name mappings */
static struct exynos5410_clock_id {
u_int id;
const char *name;
} exynos5410_clock_ids[] = {
/* core clocks */
{ 1, "fin_pll" },
{ 2, "fout_apll" },
{ 3, "fout_cpll" },
{ 4, "fout_dpll" },
{ 5, "fout_mpll" },
{ 6, "fout_kpll" },
{ 7, "fout_epll" },
/* gate for special clocks (sclk) */
{ 128, "sclk_uart0" },
{ 129, "sclk_uart1" },
{ 130, "sclk_uart2" },
{ 131, "sclk_uart3" },
{ 132, "sclk_mmc0" },
{ 133, "sclk_mmc1" },
{ 134, "sclk_mmc2" },
{ 150, "sclk_usbd300" },
{ 151, "sclk_usbd301" },
{ 152, "sclk_usbphy300" },
{ 153, "sclk_usbphy301" },
{ 155, "sclk_pwm" },
/* gate clocks */
{ 257, "uart0" },
{ 258, "uart1" },
{ 259, "uart2" },
{ 260, "uart3" },
{ 261, "i2c0" },
{ 262, "i2c1" },
{ 263, "i2c2" },
{ 264, "i2c3" },
{ 265, "usi0" },
{ 266, "usi1" },
{ 267, "usi2" },
{ 268, "usi3" },
{ 279, "pwm" },
{ 315, "mct" },
{ 316, "wdt" },
{ 317, "rtc" },
{ 318, "tmu" },
{ 351, "mmc0" },
{ 352, "mmc1" },
{ 353, "mmc2" },
{ 362, "pdma0" },
{ 363, "pdma1" },
{ 365, "usbh20" },
{ 366, "usbd300" },
{ 367, "usbd301" },
{ 471, "sss" },
};
static struct clk *exynos5410_clock_get(void *, const char *);
static void exynos5410_clock_put(void *, struct clk *);
static u_int exynos5410_clock_get_rate(void *, struct clk *);
static int exynos5410_clock_set_rate(void *, struct clk *, u_int);
static int exynos5410_clock_enable(void *, struct clk *);
static int exynos5410_clock_disable(void *, struct clk *);
static int exynos5410_clock_set_parent(void *, struct clk *, struct clk *);
static struct clk *exynos5410_clock_get_parent(void *, struct clk *);
static const struct clk_funcs exynos5410_clock_funcs = {
.get = exynos5410_clock_get,
.put = exynos5410_clock_put,
.get_rate = exynos5410_clock_get_rate,
.set_rate = exynos5410_clock_set_rate,
.enable = exynos5410_clock_enable,
.disable = exynos5410_clock_disable,
.set_parent = exynos5410_clock_set_parent,
.get_parent = exynos5410_clock_get_parent,
};
#define CLK_FIXED(_name, _rate) { \
.base = { .name = (_name) }, .type = EXYNOS_CLK_FIXED, \
.u = { .fixed = { .rate = (_rate) } } \
}
#define CLK_PLL(_name, _parent, _lock, _con0) { \
.base = { .name = (_name) }, .type = EXYNOS_CLK_PLL, \
.parent = (_parent), \
.u = { \
.pll = { \
.lock_reg = (_lock), \
.con0_reg = (_con0), \
} \
} \
}
#define CLK_MUXF(_name, _alias, _reg, _bits, _f, _p) { \
.base = { .name = (_name), .flags = (_f) }, \
.type = EXYNOS_CLK_MUX, \
.alias = (_alias), \
.u = { \
.mux = { \
.nparents = __arraycount(_p), \
.parents = (_p), \
.reg = (_reg), \
.bits = (_bits) \
} \
} \
}
#define CLK_MUXA(_name, _alias, _reg, _bits, _p) \
CLK_MUXF(_name, _alias, _reg, _bits, 0, _p)
#define CLK_MUX(_name, _reg, _bits, _p) \
CLK_MUXF(_name, NULL, _reg, _bits, 0, _p)
#define CLK_DIVF(_name, _parent, _reg, _bits, _f) { \
.base = { .name = (_name), .flags = (_f) }, \
.type = EXYNOS_CLK_DIV, \
.parent = (_parent), \
.u = { \
.div = { \
.reg = (_reg), \
.bits = (_bits) \
} \
} \
}
#define CLK_DIV(_name, _parent, _reg, _bits) \
CLK_DIVF(_name, _parent, _reg, _bits, 0)
#define CLK_GATE(_name, _parent, _reg, _bits, _f) { \
.base = { .name = (_name), .flags = (_f) }, \
.type = EXYNOS_CLK_GATE, \
.parent = (_parent), \
.u = { \
.gate = { \
.reg = (_reg), \
.bits = (_bits) \
} \
} \
}
#define EXYNOS5410_APLL_LOCK 0x00000
#define EXYNOS5410_APLL_CON0 0x00100
#define EXYNOS5410_MPLL_LOCK 0x04000
#define EXYNOS5410_MPLL_CON0 0x04100
#define EXYNOS5410_CPLL_LOCK 0x10020
#define EXYNOS5410_EPLL_LOCK 0x10040
#define EXYNOS5410_CPLL_CON0 0x10120
#define EXYNOS5410_EPLL_CON0 0x10130
#define EXYNOS5410_EPLL_CON1 0x10134
#define EXYNOS5410_EPLL_CON2 0x10138
#define EXYNOS5410_BPLL_LOCK 0x20010
#define EXYNOS5410_BPLL_CON0 0x20110
#define EXYNOS5410_KPLL_LOCK 0x28000
#define EXYNOS5410_KPLL_CON0 0x28100
#define EXYNOS5410_SRC_CPU 0x00200
#define EXYNOS5410_SRC_CPERI1 0x04204
#define EXYNOS5410_SRC_TOP0 0x10210
#define EXYNOS5410_SRC_TOP1 0x10214
#define EXYNOS5410_SRC_TOP2 0x10218
#define EXYNOS5410_SRC_FSYS 0x10244
#define EXYNOS5410_SRC_PERIC0 0x10250
#define EXYNOS5410_SRC_MASK_FSYS 0x10340
#define EXYNOS5410_SRC_MASK_PERIC0 0x10350
#define EXYNOS5410_SRC_CDREX 0x20200
#define EXYNOS5410_SRC_KFC 0x28200
#define EXYNOS5410_DIV_CPU0 0x00500
#define EXYNOS5410_DIV_TOP0 0x10510
#define EXYNOS5410_DIV_TOP1 0x10514
#define EXYNOS5410_DIV_FSYS0 0x10548
#define EXYNOS5410_DIV_FSYS1 0x1054c
#define EXYNOS5410_DIV_FSYS2 0x10550
#define EXYNOS5410_DIV_PERIC0 0x10558
#define EXYNOS5410_DIV_PERIC3 0x10564
#define EXYNOS5410_DIV_KFC0 0x28500
#define EXYNOS5410_GATE_IP_G2D 0x08800
#define EXYNOS5410_GATE_BUS_FSYS0 0x10740
#define EXYNOS5410_GATE_TOP_SCLK_FSYS 0x10840
#define EXYNOS5410_GATE_TOP_SCLK_PERIC 0x10850
#define EXYNOS5410_GATE_IP_FSYS 0x10944
#define EXYNOS5410_GATE_IP_PERIC 0x10950
#define EXYNOS5410_GATE_IP_PERIS 0x10960
static const char *mout_apll_p[] = { "fin_pll", "fout_apll" };
static const char *mout_bpll_p[] = { "fin_pll", "fout_bpll" };
static const char *mout_cpll_p[] = { "fin_pll", "fout_cpll" };
static const char *mout_epll_p[] = { "fin_pll", "fout_epll" };
static const char *mout_mpll_p[] = { "fin_pll", "fout_mpll" };
static const char *mout_kpll_p[] = { "fin_pll", "fout_kpll" };
static const char *mout_cpu_p[] = { "mout_apll", "sclk_mpll" };
static const char *mout_kfc_p[] = { "mout_kpll", "sclk_mpll" };
static const char *mout_mpll_user_p[] = { "fin_pll", "sclk_mpll" };
static const char *mout_bpll_user_p[] = { "fin_pll", "sclk_bpll" };
static const char *mout_mpll_bpll_p[] =
{ "sclk_mpll_muxed", "sclk_bpll_muxed" };
static const char *mout_sclk_mpll_bpll_p[] = { "sclk_mpll_bpll", "fin_pll" };
static const char *mout_group2_p[] =
{ "fin_pll", "fin_pll", "none", "none", "none", "none",
"sclk_mpll_bpll", "none", "none", "sclk_cpll" };
static struct exynos_clk exynos5410_clocks[] = {
CLK_FIXED("fin_pll", EXYNOS_F_IN_FREQ),
CLK_PLL("fout_apll", "fin_pll", EXYNOS5410_APLL_LOCK,
EXYNOS5410_APLL_CON0),
CLK_PLL("fout_bpll", "fin_pll", EXYNOS5410_BPLL_LOCK,
EXYNOS5410_BPLL_CON0),
CLK_PLL("fout_cpll", "fin_pll", EXYNOS5410_CPLL_LOCK,
EXYNOS5410_CPLL_CON0),
CLK_PLL("fout_epll", "fin_pll", EXYNOS5410_EPLL_LOCK,
EXYNOS5410_EPLL_CON0),
CLK_PLL("fout_mpll", "fin_pll", EXYNOS5410_MPLL_LOCK,
EXYNOS5410_MPLL_CON0),
CLK_PLL("fout_kpll", "fin_pll", EXYNOS5410_KPLL_LOCK,
EXYNOS5410_KPLL_CON0),
CLK_MUX("mout_apll", EXYNOS5410_SRC_CPU, __BIT(0), mout_apll_p),
CLK_MUX("mout_cpu", EXYNOS5410_SRC_CPU, __BIT(16), mout_cpu_p),
CLK_MUX("mout_kpll", EXYNOS5410_SRC_KFC, __BIT(0), mout_kpll_p),
CLK_MUX("mout_kfc", EXYNOS5410_SRC_KFC, __BIT(16), mout_kfc_p),
CLK_MUX("sclk_mpll", EXYNOS5410_SRC_CPERI1, __BIT(8), mout_mpll_p),
CLK_MUX("sclk_mpll_muxed", EXYNOS5410_SRC_TOP2, __BIT(20), mout_mpll_user_p),
CLK_MUX("sclk_bpll", EXYNOS5410_SRC_CDREX, __BIT(0), mout_bpll_p),
CLK_MUX("sclk_bpll_muxed", EXYNOS5410_SRC_TOP2, __BIT(24), mout_bpll_user_p),
CLK_MUX("sclk_epll", EXYNOS5410_SRC_TOP2, __BIT(12), mout_epll_p),
CLK_MUX("sclk_cpll", EXYNOS5410_SRC_TOP2, __BIT(8), mout_cpll_p),
CLK_MUX("sclk_mpll_bpll", EXYNOS5410_SRC_TOP1, __BIT(20), mout_mpll_bpll_p),
CLK_MUX("mout_mmc0", EXYNOS5410_SRC_FSYS, __BITS(3,0), mout_group2_p),
CLK_MUX("mout_mmc1", EXYNOS5410_SRC_FSYS, __BITS(7,4), mout_group2_p),
CLK_MUX("mout_mmc2", EXYNOS5410_SRC_FSYS, __BITS(11,8), mout_group2_p),
CLK_MUX("mout_usbd300", EXYNOS5410_SRC_FSYS, __BIT(28), mout_sclk_mpll_bpll_p),
CLK_MUX("mout_usbd301", EXYNOS5410_SRC_FSYS, __BIT(29), mout_sclk_mpll_bpll_p),
CLK_MUX("mout_uart0", EXYNOS5410_SRC_PERIC0, __BITS(3,0), mout_group2_p),
CLK_MUX("mout_uart1", EXYNOS5410_SRC_PERIC0, __BITS(7,4), mout_group2_p),
CLK_MUX("mout_uart2", EXYNOS5410_SRC_PERIC0, __BITS(11,8), mout_group2_p),
CLK_MUX("mout_uart3", EXYNOS5410_SRC_PERIC0, __BITS(15,12), mout_group2_p),
CLK_MUX("mout_pwm", EXYNOS5410_SRC_PERIC0, __BITS(27,24), mout_group2_p),
CLK_MUX("mout_aclk200", EXYNOS5410_SRC_TOP0, __BIT(12), mout_mpll_bpll_p),
CLK_MUX("mout_aclk400", EXYNOS5410_SRC_TOP0, __BIT(20), mout_mpll_bpll_p),
CLK_DIV("div_arm", "mout_cpu", EXYNOS5410_DIV_CPU0, __BITS(2,0)),
CLK_DIV("div_arm2", "div_arm", EXYNOS5410_DIV_CPU0, __BITS(30,28)),
CLK_DIV("div_acp", "div_arm2", EXYNOS5410_DIV_CPU0, __BITS(10,8)),
CLK_DIV("div_cpud", "div_arm2", EXYNOS5410_DIV_CPU0, __BITS(6,4)),
CLK_DIV("div_atb", "div_arm2", EXYNOS5410_DIV_CPU0, __BITS(18,16)),
CLK_DIV("pclk_dbg", "div_arm2", EXYNOS5410_DIV_CPU0, __BITS(22,20)),
CLK_DIV("div_kfc", "mout_kfc", EXYNOS5410_DIV_KFC0, __BITS(2,0)),
CLK_DIV("div_aclk", "div_kfc", EXYNOS5410_DIV_KFC0, __BITS(6,4)),
CLK_DIV("div_pclk", "div_kfc", EXYNOS5410_DIV_KFC0, __BITS(22,20)),
CLK_DIV("aclk66_pre", "sclk_mpll_muxed", EXYNOS5410_DIV_TOP1, __BITS(26,24)),
CLK_DIV("aclk66", "aclk66_pre", EXYNOS5410_DIV_TOP0, __BITS(2,0)),
CLK_DIV("dout_usbphy300", "mout_usbd300", EXYNOS5410_DIV_FSYS0, __BITS(19,16)),
CLK_DIV("dout_usbphy301", "mout_usbd301", EXYNOS5410_DIV_FSYS0, __BITS(23,20)),
CLK_DIV("dout_usbd300", "mout_usbd300", EXYNOS5410_DIV_FSYS0, __BITS(27,24)),
CLK_DIV("dout_usbd301", "mout_usbd301", EXYNOS5410_DIV_FSYS0, __BITS(31,28)),
CLK_DIV("dout_mmc0", "mout_mmc0", EXYNOS5410_DIV_FSYS1, __BITS(3,0)),
CLK_DIV("dout_mmc1", "mout_mmc1", EXYNOS5410_DIV_FSYS1, __BITS(19,16)),
CLK_DIV("dout_mmc2", "mout_mmc2", EXYNOS5410_DIV_FSYS2, __BITS(3,0)),
CLK_DIVF("dout_mmc_pre0", "dout_mmc0", EXYNOS5410_DIV_FSYS1, __BITS(15,8),
CLK_SET_RATE_PARENT),
CLK_DIVF("dout_mmc_pre1", "dout_mmc1", EXYNOS5410_DIV_FSYS1, __BITS(31,24),
CLK_SET_RATE_PARENT),
CLK_DIVF("dout_mmc_pre2", "dout_mmc2", EXYNOS5410_DIV_FSYS2, __BITS(15,8),
CLK_SET_RATE_PARENT),
CLK_DIV("div_uart0", "mout_uart0", EXYNOS5410_DIV_PERIC0, __BITS(3,0)),
CLK_DIV("div_uart1", "mout_uart1", EXYNOS5410_DIV_PERIC0, __BITS(7,4)),
CLK_DIV("div_uart2", "mout_uart2", EXYNOS5410_DIV_PERIC0, __BITS(11,8)),
CLK_DIV("div_uart3", "mout_uart3", EXYNOS5410_DIV_PERIC0, __BITS(15,12)),
CLK_DIV("dout_pwm", "mout_pwm", EXYNOS5410_DIV_PERIC3, __BITS(3,0)),
CLK_DIV("aclk200", "mout_aclk200", EXYNOS5410_DIV_TOP0, __BITS(14,12)),
CLK_DIV("aclk266", "sclk_mpll_muxed", EXYNOS5410_DIV_TOP0, __BITS(18,16)),
CLK_DIV("aclk400", "mout_aclk400", EXYNOS5410_DIV_TOP0, __BITS(26,24)),
CLK_GATE("sss", "aclk266", EXYNOS5410_GATE_IP_G2D, __BIT(2), 0),
CLK_GATE("mct", "aclk66", EXYNOS5410_GATE_IP_PERIS, __BIT(18), 0),
CLK_GATE("wdt", "aclk66", EXYNOS5410_GATE_IP_PERIS, __BIT(19), 0),
CLK_GATE("rtc", "aclk66", EXYNOS5410_GATE_IP_PERIS, __BIT(20), 0),
CLK_GATE("tmu", "aclk66", EXYNOS5410_GATE_IP_PERIS, __BIT(21), 0),
CLK_GATE("sclk_mmc0", "dout_mmc_pre0", EXYNOS5410_SRC_MASK_FSYS,
__BIT(0), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_mmc1", "dout_mmc_pre1", EXYNOS5410_SRC_MASK_FSYS,
__BIT(4), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_mmc2", "dout_mmc_pre2", EXYNOS5410_SRC_MASK_FSYS,
__BIT(8), CLK_SET_RATE_PARENT),
CLK_GATE("mmc0", "aclk200", EXYNOS5410_GATE_BUS_FSYS0, __BIT(12), 0),
CLK_GATE("mmc1", "aclk200", EXYNOS5410_GATE_BUS_FSYS0, __BIT(13), 0),
CLK_GATE("mmc2", "aclk200", EXYNOS5410_GATE_BUS_FSYS0, __BIT(14), 0),
CLK_GATE("pdma1", "aclk200", EXYNOS5410_GATE_BUS_FSYS0, __BIT(2), 0),
CLK_GATE("pdma0", "aclk200", EXYNOS5410_GATE_BUS_FSYS0, __BIT(1), 0),
CLK_GATE("sclk_usbphy301", "dout_usbphy301", EXYNOS5410_GATE_TOP_SCLK_FSYS,
__BIT(7), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_usbphy300", "dout_usbphy300", EXYNOS5410_GATE_TOP_SCLK_FSYS,
__BIT(8), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_usbd301", "dout_usbd301", EXYNOS5410_GATE_TOP_SCLK_FSYS,
__BIT(9), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_usbd301", "dout_usbd301", EXYNOS5410_GATE_TOP_SCLK_FSYS,
__BIT(10), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_pwm", "dout_pwm", EXYNOS5410_GATE_TOP_SCLK_PERIC,
__BIT(11), CLK_SET_RATE_PARENT),
CLK_GATE("uart0", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(0), 0),
CLK_GATE("uart1", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(1), 0),
CLK_GATE("uart2", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(2), 0),
CLK_GATE("uart3", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(3), 0),
CLK_GATE("i2c0", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(6), 0),
CLK_GATE("i2c1", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(7), 0),
CLK_GATE("i2c2", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(8), 0),
CLK_GATE("i2c3", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(9), 0),
CLK_GATE("usi0", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(10), 0),
CLK_GATE("usi1", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(11), 0),
CLK_GATE("usi2", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(12), 0),
CLK_GATE("usi3", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(13), 0),
CLK_GATE("pwm", "aclk66", EXYNOS5410_GATE_IP_PERIC, __BIT(24), 0),
CLK_GATE("sclk_uart0", "div_uart0", EXYNOS5410_SRC_MASK_PERIC0,
__BIT(0), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_uart1", "div_uart1", EXYNOS5410_SRC_MASK_PERIC0,
__BIT(4), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_uart2", "div_uart2", EXYNOS5410_SRC_MASK_PERIC0,
__BIT(8), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_uart3", "div_uart3", EXYNOS5410_SRC_MASK_PERIC0,
__BIT(12), CLK_SET_RATE_PARENT),
CLK_GATE("usbh20", "aclk200", EXYNOS5410_GATE_IP_FSYS, __BIT(18), 0),
CLK_GATE("usbd301", "aclk200", EXYNOS5410_GATE_IP_FSYS, __BIT(19), 0),
CLK_GATE("usbd300", "aclk200", EXYNOS5410_GATE_IP_FSYS, __BIT(20), 0),
};
static int exynos5410_clock_match(device_t, cfdata_t, void *);
static void exynos5410_clock_attach(device_t, device_t, void *);
struct exynos5410_clock_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
struct clk_domain sc_clkdom;
};
static void exynos5410_clock_print_header(void);
static void exynos5410_clock_print(struct exynos5410_clock_softc *,
struct exynos_clk *);
CFATTACH_DECL_NEW(exynos5410_clock, sizeof(struct exynos5410_clock_softc),
exynos5410_clock_match, exynos5410_clock_attach, NULL, NULL);
#define CLOCK_READ(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define CLOCK_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
static int
exynos5410_clock_match(device_t parent, cfdata_t cf, void *aux)
{
const char * const compatible[] = { "samsung,exynos5410-clock", NULL };
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
exynos5410_clock_attach(device_t parent, device_t self, void *aux)
{
struct exynos5410_clock_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
bus_addr_t addr;
bus_size_t size;
int error;
if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
sc->sc_dev = self;
sc->sc_bst = faa->faa_bst;
error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
if (error) {
aprint_error(": couldn't map %#llx: %d",
(uint64_t)addr, error);
return;
}
aprint_naive("\n");
aprint_normal(": Exynos5410 Clock Controller\n");
sc->sc_clkdom.funcs = &exynos5410_clock_funcs;
sc->sc_clkdom.priv = sc;
for (u_int n = 0; n < __arraycount(exynos5410_clocks); n++) {
exynos5410_clocks[n].base.domain = &sc->sc_clkdom;
}
fdtbus_register_clock_controller(self, faa->faa_phandle,
&exynos5410_car_fdtclock_funcs);
exynos5410_clock_print_header();
for (u_int n = 0; n < __arraycount(exynos5410_clocks); n++) {
exynos5410_clock_print(sc, &exynos5410_clocks[n]);
}
}
static struct exynos_clk *
exynos5410_clock_find(const char *name)
{
u_int n;
for (n = 0; n < __arraycount(exynos5410_clocks); n++) {
if (strcmp(exynos5410_clocks[n].base.name, name) == 0) {
return &exynos5410_clocks[n];
}
}
return NULL;
}
static struct exynos_clk *
exynos5410_clock_find_by_id(u_int clock_id)
{
u_int n;
for (n = 0; n < __arraycount(exynos5410_clock_ids); n++) {
if (exynos5410_clock_ids[n].id == clock_id) {
const char *name = exynos5410_clock_ids[n].name;
return exynos5410_clock_find(name);
}
}
return NULL;
}
static void
exynos5410_clock_print_header(void)
{
printf(" %-10s %2s %-10s %-5s %10s\n",
"clock", "", "parent", "type", "rate");
printf(" %-10s %2s %-10s %-5s %10s\n",
"=====", "", "======", "====", "====");
}
static void
exynos5410_clock_print(struct exynos5410_clock_softc *sc,
struct exynos_clk *eclk)
{
struct exynos_clk *eclk_parent;
struct clk *clk_parent;
const char *type = "?";
switch (eclk->type) {
case EXYNOS_CLK_FIXED:
type = "fixed";
break;
case EXYNOS_CLK_PLL:
type = "pll";
break;
case EXYNOS_CLK_MUX:
type = "mux";
break;
case EXYNOS_CLK_DIV:
type = "div";
break;
case EXYNOS_CLK_GATE:
type = "gate";
break;
}
clk_parent = exynos5410_clock_get_parent(sc, &eclk->base);
eclk_parent = (struct exynos_clk *)clk_parent;
printf(" %-10s %2s %-10s %-5s %10d Hz\n",
eclk->base.name,
eclk_parent ? "<-" : "",
eclk_parent ? eclk_parent->base.name : "",
type, clk_get_rate(&eclk->base));
}
static struct clk *
exynos5410_clock_decode(device_t dev, const void *data, size_t len)
{
struct exynos_clk *eclk;
/* #clock-cells should be 1 */
if (len != 4) {
return NULL;
}
const u_int clock_id = be32dec(data);
eclk = exynos5410_clock_find_by_id(clock_id);
if (eclk)
return &eclk->base;
return NULL;
}
static u_int
exynos5410_clock_get_rate_pll(struct exynos5410_clock_softc *sc,
struct exynos_clk *eclk)
{
struct exynos_pll_clk *epll = &eclk->u.pll;
struct exynos_clk *clk_parent;
KASSERT(eclk->type == EXYNOS_CLK_PLL);
clk_parent = exynos5410_clock_find(eclk->parent);
KASSERT(clk_parent != NULL);
const u_int rate_parent = exynos5410_clock_get_rate(sc,
&clk_parent->base);
const uint32_t v = CLOCK_READ(sc, epll->con0_reg);
return PLL_FREQ(rate_parent, v);
}
static int
exynos5410_clock_set_rate_pll(struct exynos5410_clock_softc *sc,
struct exynos_clk *eclk, u_int rate)
{
/* TODO */
return EOPNOTSUPP;
}
static int
exynos5410_clock_set_parent_mux(struct exynos5410_clock_softc *sc,
struct exynos_clk *eclk, struct exynos_clk *eclk_parent)
{
struct exynos_mux_clk *emux = &eclk->u.mux;
const char *pname = eclk_parent->base.name;
u_int sel;
KASSERT(eclk->type == EXYNOS_CLK_MUX);
for (sel = 0; sel < emux->nparents; sel++) {
if (strcmp(pname, emux->parents[sel]) == 0) {
break;
}
}
if (sel == emux->nparents) {
return EINVAL;
}
uint32_t v = CLOCK_READ(sc, emux->reg);
v &= ~emux->bits;
v |= __SHIFTIN(sel, emux->bits);
CLOCK_WRITE(sc, emux->reg, v);
return 0;
}
static struct exynos_clk *
exynos5410_clock_get_parent_mux(struct exynos5410_clock_softc *sc,
struct exynos_clk *eclk)
{
struct exynos_mux_clk *emux = &eclk->u.mux;
KASSERT(eclk->type == EXYNOS_CLK_MUX);
const uint32_t v = CLOCK_READ(sc, emux->reg);
const u_int sel = __SHIFTOUT(v, emux->bits);
KASSERT(sel < emux->nparents);
return exynos5410_clock_find(emux->parents[sel]);
}
static u_int
exynos5410_clock_get_rate_div(struct exynos5410_clock_softc *sc,
struct exynos_clk *eclk)
{
struct exynos_div_clk *ediv = &eclk->u.div;
struct clk *clk_parent;
KASSERT(eclk->type == EXYNOS_CLK_DIV);
clk_parent = exynos5410_clock_get_parent(sc, &eclk->base);
const u_int parent_rate = exynos5410_clock_get_rate(sc, clk_parent);
const uint32_t v = CLOCK_READ(sc, ediv->reg);
const u_int div = __SHIFTOUT(v, ediv->bits);
return parent_rate / (div + 1);
}
static int
exynos5410_clock_set_rate_div(struct exynos5410_clock_softc *sc,
struct exynos_clk *eclk, u_int rate)
{
struct exynos_div_clk *ediv = &eclk->u.div;
struct clk *clk_parent;
int tmp_div, new_div = -1;
u_int tmp_rate;
KASSERT(eclk->type == EXYNOS_CLK_DIV);
clk_parent = exynos5410_clock_get_parent(sc, &eclk->base);
const u_int parent_rate = exynos5410_clock_get_rate(sc, clk_parent);
for (tmp_div = 0; tmp_div < popcount32(ediv->bits); tmp_div++) {
tmp_rate = parent_rate / (tmp_div + 1);
if (tmp_rate <= rate) {
new_div = tmp_div;
break;
}
}
if (new_div == -1)
return EINVAL;
uint32_t v = CLOCK_READ(sc, ediv->reg);
v &= ~ediv->bits;
v |= __SHIFTIN(new_div, ediv->bits);
CLOCK_WRITE(sc, ediv->reg, v);
return 0;
}
static int
exynos5410_clock_enable_gate(struct exynos5410_clock_softc *sc,
struct exynos_clk *eclk, bool enable)
{
struct exynos_gate_clk *egate = &eclk->u.gate;
KASSERT(eclk->type == EXYNOS_CLK_GATE);
uint32_t v = CLOCK_READ(sc, egate->reg);
if (enable) {
v |= egate->bits;
} else {
v &= ~egate->bits;
}
CLOCK_WRITE(sc, egate->reg, v);
return 0;
}
/*
* clk api
*/
static struct clk *
exynos5410_clock_get(void *priv, const char *name)
{
struct exynos_clk *eclk;
eclk = exynos5410_clock_find(name);
if (eclk == NULL)
return NULL;
atomic_inc_uint(&eclk->refcnt);
return &eclk->base;
}
static void
exynos5410_clock_put(void *priv, struct clk *clk)
{
struct exynos_clk *eclk = (struct exynos_clk *)clk;
KASSERT(eclk->refcnt > 0);
atomic_dec_uint(&eclk->refcnt);
}
static u_int
exynos5410_clock_get_rate(void *priv, struct clk *clk)
{
struct exynos_clk *eclk = (struct exynos_clk *)clk;
struct clk *clk_parent;
switch (eclk->type) {
case EXYNOS_CLK_FIXED:
return eclk->u.fixed.rate;
case EXYNOS_CLK_PLL:
return exynos5410_clock_get_rate_pll(priv, eclk);
case EXYNOS_CLK_MUX:
case EXYNOS_CLK_GATE:
clk_parent = exynos5410_clock_get_parent(priv, clk);
return exynos5410_clock_get_rate(priv, clk_parent);
case EXYNOS_CLK_DIV:
return exynos5410_clock_get_rate_div(priv, eclk);
default:
panic("exynos5410: unknown eclk type %d", eclk->type);
}
}
static int
exynos5410_clock_set_rate(void *priv, struct clk *clk, u_int rate)
{
struct exynos_clk *eclk = (struct exynos_clk *)clk;
KASSERT((clk->flags & CLK_SET_RATE_PARENT) == 0);
switch (eclk->type) {
case EXYNOS_CLK_FIXED:
return EIO;
case EXYNOS_CLK_PLL:
return exynos5410_clock_set_rate_pll(priv, eclk, rate);
case EXYNOS_CLK_MUX:
return EIO;
case EXYNOS_CLK_DIV:
return exynos5410_clock_set_rate_div(priv, eclk, rate);
case EXYNOS_CLK_GATE:
return EINVAL;
default:
panic("exynos5410: unknown eclk type %d", eclk->type);
}
}
static int
exynos5410_clock_enable(void *priv, struct clk *clk)
{
struct exynos_clk *eclk = (struct exynos_clk *)clk;
switch (eclk->type) {
case EXYNOS_CLK_FIXED:
return 0; /* always on */
case EXYNOS_CLK_PLL:
return 0; /* XXX */
case EXYNOS_CLK_MUX:
case EXYNOS_CLK_DIV:
return 0;
case EXYNOS_CLK_GATE:
return exynos5410_clock_enable_gate(priv, eclk, true);
default:
panic("exynos5410: unknown eclk type %d", eclk->type);
}
}
static int
exynos5410_clock_disable(void *priv, struct clk *clk)
{
struct exynos_clk *eclk = (struct exynos_clk *)clk;
switch (eclk->type) {
case EXYNOS_CLK_FIXED:
return EINVAL; /* always on */
case EXYNOS_CLK_PLL:
return EINVAL; /* XXX */
case EXYNOS_CLK_MUX:
case EXYNOS_CLK_DIV:
return EINVAL;
case EXYNOS_CLK_GATE:
return exynos5410_clock_enable_gate(priv, eclk, false);
default:
panic("exynos5410: unknown eclk type %d", eclk->type);
}
}
static int
exynos5410_clock_set_parent(void *priv, struct clk *clk, struct clk *clk_parent)
{
struct exynos_clk *eclk = (struct exynos_clk *)clk;
struct exynos_clk *eclk_parent = (struct exynos_clk *)clk_parent;
switch (eclk->type) {
case EXYNOS_CLK_FIXED:
case EXYNOS_CLK_PLL:
case EXYNOS_CLK_DIV:
case EXYNOS_CLK_GATE:
return EINVAL;
case EXYNOS_CLK_MUX:
return exynos5410_clock_set_parent_mux(priv, eclk, eclk_parent);
default:
panic("exynos5410: unknown eclk type %d", eclk->type);
}
}
static struct clk *
exynos5410_clock_get_parent(void *priv, struct clk *clk)
{
struct exynos_clk *eclk = (struct exynos_clk *)clk;
struct exynos_clk *eclk_parent = NULL;
switch (eclk->type) {
case EXYNOS_CLK_FIXED:
case EXYNOS_CLK_PLL:
case EXYNOS_CLK_DIV:
case EXYNOS_CLK_GATE:
if (eclk->parent != NULL) {
eclk_parent = exynos5410_clock_find(eclk->parent);
}
break;
case EXYNOS_CLK_MUX:
eclk_parent = exynos5410_clock_get_parent_mux(priv, eclk);
break;
default:
panic("exynos5410: unknown eclk type %d", eclk->type);
}
return (struct clk *)eclk_parent;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos5422_clock.c,v 1.5 2017/04/16 15:52:43 jmcneill Exp $ */
/* $NetBSD: exynos5422_clock.c,v 1.5.4.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@ -29,7 +29,7 @@
#include "locators.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exynos5422_clock.c,v 1.5 2017/04/16 15:52:43 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: exynos5422_clock.c,v 1.5.4.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -277,13 +277,13 @@ static const struct clk_funcs exynos5422_clock_funcs = {
.u = { .fixed = { .rate = (_rate) } } \
}
#define CLK_PLL(_name, _parent, _base) { \
#define CLK_PLL(_name, _parent, _lock, _con0) { \
.base = { .name = (_name) }, .type = EXYNOS_CLK_PLL, \
.parent = (_parent), \
.u = { \
.pll = { \
.con0_reg = (_base) + PLL_CON0_OFFSET, \
.lock_reg = (_base) + PLL_LOCK_OFFSET, \
.lock_reg = (_lock), \
.con0_reg = (_con0), \
} \
} \
}
@ -331,17 +331,32 @@ static const struct clk_funcs exynos5422_clock_funcs = {
} \
}
#define EXYNOS5422_APLL_BASE 0x00000
#define EXYNOS5422_CPLL_BASE 0x10020
#define EXYNOS5422_DPLL_BASE 0x10030
#define EXYNOS5422_EPLL_BASE 0x10040
#define EXYNOS5422_RPLL_BASE 0x10050
#define EXYNOS5422_IPLL_BASE 0x10060
#define EXYNOS5422_SPLL_BASE 0x10070
#define EXYNOS5422_VPLL_BASE 0x10080
#define EXYNOS5422_MPLL_BASE 0x10090
#define EXYNOS5422_BPLL_BASE 0x20010
#define EXYNOS5422_KPLL_BASE 0x28000
#define EXYNOS5422_APLL_LOCK 0x00000
#define EXYNOS5422_APLL_CON0 0x00100
#define EXYNOS5422_CPLL_LOCK 0x10020
#define EXYNOS5422_DPLL_LOCK 0x10030
#define EXYNOS5422_EPLL_LOCK 0x10040
#define EXYNOS5422_RPLL_LOCK 0x10050
#define EXYNOS5422_IPLL_LOCK 0x10060
#define EXYNOS5422_SPLL_LOCK 0x10070
#define EXYNOS5422_VPLL_LOCK 0x10080
#define EXYNOS5422_MPLL_LOCK 0x10090
#define EXYNOS5422_CPLL_CON0 0x10120
#define EXYNOS5422_DPLL_CON0 0x10128
#define EXYNOS5422_EPLL_CON0 0x10130
#define EXYNOS5422_EPLL_CON1 0x10134
#define EXYNOS5422_EPLL_CON2 0x10138
#define EXYNOS5422_RPLL_CON0 0x10140
#define EXYNOS5422_RPLL_CON1 0x10144
#define EXYNOS5422_RPLL_CON2 0x10148
#define EXYNOS5422_IPLL_CON0 0x10150
#define EXYNOS5422_SPLL_CON0 0x10160
#define EXYNOS5422_VPLL_CON0 0x10170
#define EXYNOS5422_MPLL_CON0 0x10180
#define EXYNOS5422_BPLL_LOCK 0x20010
#define EXYNOS5422_BPLL_CON0 0x20110
#define EXYNOS5422_KPLL_LOCK 0x28000
#define EXYNOS5422_KPLL_CON0 0x28100
#define EXYNOS5422_SRC_CPU 0x00200
#define EXYNOS5422_SRC_TOP0 0x10200
@ -363,8 +378,10 @@ static const struct clk_funcs exynos5422_clock_funcs = {
#define EXYNOS5422_SRC_TOP12 0x10280
#define EXYNOS5422_DIV_FSYS1 0x1054c
#define EXYNOS5422_DIV_PERIC0 0x10558
#define EXYNOS5422_GATE_TOP_SCLK_FSYS 0x10840
#define EXYNOS5422_GATE_TOP_SCLK_PERIC 0x10850
static const char *mout_cpll_p[] = { "fin_pll", "fout_cpll" };
static const char *mout_dpll_p[] = { "fin_pll", "fout_dpll" };
@ -380,17 +397,28 @@ static const char *mout_group2_p[] =
static struct exynos_clk exynos5422_clocks[] = {
CLK_FIXED("fin_pll", EXYNOS_F_IN_FREQ),
CLK_PLL("fout_apll", "fin_pll", EXYNOS5422_APLL_BASE),
CLK_PLL("fout_cpll", "fin_pll", EXYNOS5422_CPLL_BASE),
CLK_PLL("fout_dpll", "fin_pll", EXYNOS5422_DPLL_BASE),
CLK_PLL("fout_epll", "fin_pll", EXYNOS5422_EPLL_BASE),
CLK_PLL("fout_rpll", "fin_pll", EXYNOS5422_RPLL_BASE),
CLK_PLL("fout_ipll", "fin_pll", EXYNOS5422_IPLL_BASE),
CLK_PLL("fout_spll", "fin_pll", EXYNOS5422_SPLL_BASE),
CLK_PLL("fout_vpll", "fin_pll", EXYNOS5422_VPLL_BASE),
CLK_PLL("fout_mpll", "fin_pll", EXYNOS5422_MPLL_BASE),
CLK_PLL("fout_bpll", "fin_pll", EXYNOS5422_BPLL_BASE),
CLK_PLL("fout_kpll", "fin_pll", EXYNOS5422_KPLL_BASE),
CLK_PLL("fout_apll", "fin_pll", EXYNOS5422_APLL_LOCK,
EXYNOS5422_APLL_CON0),
CLK_PLL("fout_cpll", "fin_pll", EXYNOS5422_CPLL_LOCK,
EXYNOS5422_CPLL_CON0),
CLK_PLL("fout_dpll", "fin_pll", EXYNOS5422_DPLL_LOCK,
EXYNOS5422_DPLL_CON0),
CLK_PLL("fout_epll", "fin_pll", EXYNOS5422_EPLL_LOCK,
EXYNOS5422_EPLL_CON0),
CLK_PLL("fout_rpll", "fin_pll", EXYNOS5422_RPLL_LOCK,
EXYNOS5422_RPLL_CON0),
CLK_PLL("fout_ipll", "fin_pll", EXYNOS5422_IPLL_LOCK,
EXYNOS5422_IPLL_CON0),
CLK_PLL("fout_spll", "fin_pll", EXYNOS5422_SPLL_LOCK,
EXYNOS5422_SPLL_CON0),
CLK_PLL("fout_vpll", "fin_pll", EXYNOS5422_VPLL_LOCK,
EXYNOS5422_VPLL_CON0),
CLK_PLL("fout_mpll", "fin_pll", EXYNOS5422_MPLL_LOCK,
EXYNOS5422_MPLL_CON0),
CLK_PLL("fout_bpll", "fin_pll", EXYNOS5422_BPLL_LOCK,
EXYNOS5422_BPLL_CON0),
CLK_PLL("fout_kpll", "fin_pll", EXYNOS5422_KPLL_LOCK,
EXYNOS5422_KPLL_CON0),
CLK_MUXA("sclk_cpll", "mout_cpll", EXYNOS5422_SRC_TOP6, __BIT(28),
mout_cpll_p),
@ -413,10 +441,26 @@ static struct exynos_clk exynos5422_clocks[] = {
mout_group2_p),
CLK_MUX("mout_mmc2", EXYNOS5422_SRC_FSYS, __BITS(18,16),
mout_group2_p),
CLK_MUX("mout_uart0", EXYNOS5422_SRC_PERIC0, __BITS(6,4),
mout_group2_p),
CLK_MUX("mout_uart1", EXYNOS5422_SRC_PERIC0, __BITS(10,8),
mout_group2_p),
CLK_MUX("mout_uart2", EXYNOS5422_SRC_PERIC0, __BITS(14,12),
mout_group2_p),
CLK_MUX("mout_uart3", EXYNOS5422_SRC_PERIC0, __BITS(18,16),
mout_group2_p),
CLK_DIV("dout_mmc0", "mout_mmc0", EXYNOS5422_DIV_FSYS1, __BITS(9,0)),
CLK_DIV("dout_mmc1", "mout_mmc1", EXYNOS5422_DIV_FSYS1, __BITS(19,10)),
CLK_DIV("dout_mmc2", "mout_mmc2", EXYNOS5422_DIV_FSYS1, __BITS(29,20)),
CLK_DIV("dout_uart0", "mout_uart0", EXYNOS5422_DIV_PERIC0,
__BITS(11,8)),
CLK_DIV("dout_uart1", "mout_uart1", EXYNOS5422_DIV_PERIC0,
__BITS(15,12)),
CLK_DIV("dout_uart2", "mout_uart2", EXYNOS5422_DIV_PERIC0,
__BITS(19,16)),
CLK_DIV("dout_uart3", "mout_uart3", EXYNOS5422_DIV_PERIC0,
__BITS(23,20)),
CLK_GATE("sclk_mmc0", "dout_mmc0", EXYNOS5422_GATE_TOP_SCLK_FSYS,
__BIT(0), CLK_SET_RATE_PARENT),
@ -424,6 +468,14 @@ static struct exynos_clk exynos5422_clocks[] = {
__BIT(1), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_mmc2", "dout_mmc2", EXYNOS5422_GATE_TOP_SCLK_FSYS,
__BIT(2), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_uart0", "dout_uart0", EXYNOS5422_GATE_TOP_SCLK_PERIC,
__BIT(0), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_uart1", "dout_uart1", EXYNOS5422_GATE_TOP_SCLK_PERIC,
__BIT(1), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_uart2", "dout_uart2", EXYNOS5422_GATE_TOP_SCLK_PERIC,
__BIT(2), CLK_SET_RATE_PARENT),
CLK_GATE("sclk_uart3", "dout_uart3", EXYNOS5422_GATE_TOP_SCLK_PERIC,
__BIT(3), CLK_SET_RATE_PARENT),
};
static int exynos5422_clock_match(device_t, cfdata_t, void *);
@ -886,5 +938,5 @@ exynos5422_clock_get_parent(void *priv, struct clk *clk)
panic("exynos5422: unknown eclk type %d", eclk->type);
}
return &eclk_parent->base;
return (struct clk *)eclk_parent;
}

View File

@ -1,77 +0,0 @@
/* $NetBSD: exynos5422_dma.c,v 1.1 2015/12/11 04:05:54 marty Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Nick Hudson
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include "opt_exynos.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exynos5422_dma.c,v 1.1 2015/12/11 04:05:54 marty Exp $");
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/bus.h>
#include <arm/samsung/exynos_reg.h>
#include <arm/samsung/exynos_var.h>
struct arm32_bus_dma_tag exynos_bus_dma_tag = {
_BUS_DMAMAP_FUNCS,
_BUS_DMAMEM_FUNCS,
_BUS_DMATAG_FUNCS,
};
struct arm32_dma_range exynos_coherent_dma_ranges[1] = {
[0] = {
.dr_sysbase = 0, /* filled in */
.dr_busbase = 0, /* filled in */
.dr_flags = _BUS_DMAMAP_COHERENT,
},
};
struct arm32_bus_dma_tag exynos_coherent_bus_dma_tag = {
._ranges = exynos_coherent_dma_ranges,
._nranges = __arraycount(exynos_coherent_dma_ranges),
_BUS_DMAMAP_FUNCS,
_BUS_DMAMEM_FUNCS,
_BUS_DMATAG_FUNCS,
};
void
exynos_dma_bootstrap(psize_t memsize)
{
bus_addr_t dram_base = EXYNOS5_SDRAM_PBASE;
KASSERT(dram_base);
exynos_coherent_dma_ranges[0].dr_sysbase = dram_base;
exynos_coherent_dma_ranges[0].dr_busbase = dram_base;
exynos_coherent_dma_ranges[0].dr_len = memsize;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos_combiner.c,v 1.6 2016/01/05 21:53:48 marty Exp $ */
/* $NetBSD: exynos_combiner.c,v 1.6.10.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@ -34,7 +34,7 @@
#include "gpio.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: exynos_combiner.c,v 1.6 2016/01/05 21:53:48 marty Exp $");
__KERNEL_RCSID(1, "$NetBSD: exynos_combiner.c,v 1.6.10.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -66,6 +66,7 @@ struct exynos_combiner_irq_entry {
int (*irq_handler)(void *);
void * irq_arg;
struct exynos_combiner_irq_entry *irq_next;
bool irq_mpsafe;
};
struct exynos_combiner_irq_block {
@ -73,6 +74,7 @@ struct exynos_combiner_irq_block {
struct exynos_combiner_softc *irq_sc;
struct exynos_combiner_irq_entry *irq_entries;
struct exynos_combiner_irq_block *irq_block_next;
void *irq_ih;
};
struct exynos_combiner_softc {
@ -173,7 +175,7 @@ exynos_combiner_get_block(struct exynos_combiner_softc *sc, int block)
static struct exynos_combiner_irq_entry *
exynos_combiner_new_irq(struct exynos_combiner_irq_block *block,
int irq, int (*func)(void *), void *arg)
int irq, bool mpsafe, int (*func)(void *), void *arg)
{
struct exynos_combiner_irq_entry * n = kmem_zalloc(sizeof(*n),
KM_SLEEP);
@ -181,6 +183,7 @@ exynos_combiner_new_irq(struct exynos_combiner_irq_block *block,
n->irq_handler = func;
n->irq_next = block->irq_entries;
n->irq_arg = arg;
n->irq_mpsafe = mpsafe;
block->irq_entries = n;
return n;
}
@ -196,7 +199,8 @@ exynos_combiner_get_irq(struct exynos_combiner_irq_block *b, int irq)
return NULL;
}
static int exynos_combiner_irq(void *cookie)
static int
exynos_combiner_irq(void *cookie)
{
struct exynos_combiner_irq_block *blockp = cookie;
struct exynos_combiner_softc *sc = blockp->irq_sc;
@ -211,9 +215,13 @@ static int exynos_combiner_irq(void *cookie)
if (istatus & 1 << irq) {
struct exynos_combiner_irq_entry *e =
exynos_combiner_get_irq(blockp, irq);
if (e)
if (e) {
if (!e->irq_mpsafe)
KERNEL_LOCK(1, curlwp);
e->irq_handler(e->irq_arg);
else
if (!e->irq_mpsafe)
KERNEL_UNLOCK_ONE(curlwp);
} else
printf("%s: Unexpected irq %d, %d\n", __func__,
intr, irq);
}
@ -229,6 +237,7 @@ exynos_combiner_establish(device_t dev, u_int *specifier,
struct exynos_combiner_softc * const sc = device_private(dev);
struct exynos_combiner_irq_block *blockp;
struct exynos_combiner_irq_entry *entryp;
const bool mpsafe = (flags & FDT_INTR_MPSAFE) != 0;
const u_int intr = be32toh(specifier[0]);
const u_int irq = be32toh(specifier[1]);
@ -237,18 +246,19 @@ exynos_combiner_establish(device_t dev, u_int *specifier,
intr / COMBINER_BLOCKS_PER_GROUP * COMBINER_GROUP_SIZE
+ COMBINER_IESR_OFFSET;
blockp = exynos_combiner_get_block(sc, intr);
blockp = exynos_combiner_get_block(sc, intr);
if (!blockp) {
blockp = exynos_combiner_new_block(sc, intr);
KASSERT(blockp);
intr_establish(intr, ipl, IST_LEVEL, exynos_combiner_irq,
blockp);
blockp->irq_ih = fdtbus_intr_establish(sc->sc_phandle, intr,
IPL_VM /* XXX */, FDT_INTR_MPSAFE, exynos_combiner_irq,
blockp);
}
entryp = exynos_combiner_get_irq(blockp, irq);
if (entryp)
return NULL;
entryp = exynos_combiner_new_irq(blockp, irq, func, arg);
entryp = exynos_combiner_new_irq(blockp, irq, mpsafe, func, arg);
KASSERT(entryp);
int istatus =
@ -262,7 +272,7 @@ static void
exynos_combiner_disestablish(device_t dev, void *ih)
{
/* MJF: Find the ih and disable the handler. */
intr_disestablish(ih);
panic("exynos_combiner_disestablish not implemented");
}
static bool

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos_dwcmmc.c,v 1.3 2016/05/30 16:38:35 dholland Exp $ */
/* $NetBSD: exynos_dwcmmc.c,v 1.3.10.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exynos_dwcmmc.c,v 1.3 2016/05/30 16:38:35 dholland Exp $");
__KERNEL_RCSID(0, "$NetBSD: exynos_dwcmmc.c,v 1.3.10.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -43,11 +43,18 @@ __KERNEL_RCSID(0, "$NetBSD: exynos_dwcmmc.c,v 1.3 2016/05/30 16:38:35 dholland E
#include <dev/ic/dwc_mmc_var.h>
#include <dev/fdt/fdtvar.h>
#define FIFO_REG 0x200
#define MPS_BEGIN 0x200
#define MPS_END 0x204
#define MPS_CTRL 0x20c
#define MPS_CTRL_SECURE_WRITE __BIT(6)
#define MPS_CTRL_NON_SECURE_READ __BIT(5)
#define MPS_CTRL_NON_SECURE_WRITE __BIT(4)
#define MPS_CTRL_VALID __BIT(0)
static int exynos_dwcmmc_match(device_t, cfdata_t, void *);
static void exynos_dwcmmc_attach(device_t, device_t, void *);
static void exynos_dwcmmc_attach_i(device_t);
static int exynos_dwcmmc_card_detect(struct dwc_mmc_softc *);
struct exynos_dwcmmc_softc {
@ -137,12 +144,13 @@ exynos_dwcmmc_attach(device_t parent, device_t self, void *aux)
sc->sc_clock_freq = clk_get_rate(esc->sc_clk_ciu) / (ciu_div + 1);
sc->sc_fifo_depth = fifo_depth;
sc->sc_fifo_reg = FIFO_REG;
sc->sc_flags = DWC_MMC_F_USE_HOLD_REG | DWC_MMC_F_DMA;
esc->sc_pin_cd = fdtbus_gpio_acquire(phandle, "cd-gpios",
GPIO_PIN_INPUT);
if (esc->sc_pin_cd) {
if (esc->sc_pin_cd)
sc->sc_card_detect = exynos_dwcmmc_card_detect;
}
aprint_naive("\n");
aprint_normal(": MHS (%u Hz)\n", sc->sc_clock_freq);
@ -152,6 +160,9 @@ exynos_dwcmmc_attach(device_t parent, device_t self, void *aux)
return;
}
if (dwc_mmc_init(sc) != 0)
return;
sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_BIO, 0,
dwc_mmc_intr, sc);
if (sc->sc_ih == NULL) {
@ -161,16 +172,15 @@ exynos_dwcmmc_attach(device_t parent, device_t self, void *aux)
}
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
config_interrupts(self, exynos_dwcmmc_attach_i);
}
static void
exynos_dwcmmc_attach_i(device_t self)
{
struct exynos_dwcmmc_softc *esc = device_private(self);
struct dwc_mmc_softc *sc = &esc->sc;
dwc_mmc_init(sc);
/* Disable encryption mode */
const char * compat_enc[] = { "samsung,exynos5420-dw-mshc-smu", NULL };
if (of_match_compatible(phandle, compat_enc)) {
bus_space_write_4(sc->sc_bst, sc->sc_bsh, MPS_BEGIN, 0);
bus_space_write_4(sc->sc_bst, sc->sc_bsh, MPS_END, ~0U);
bus_space_write_4(sc->sc_bst, sc->sc_bsh, MPS_CTRL,
MPS_CTRL_NON_SECURE_READ | MPS_CTRL_NON_SECURE_WRITE |
MPS_CTRL_SECURE_WRITE | MPS_CTRL_VALID);
}
}
static int

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos_i2c.c,v 1.11 2016/02/14 19:54:20 chs Exp $ */
/* $NetBSD: exynos_i2c.c,v 1.11.10.1 2017/07/18 19:13:08 snj Exp $ */
/*
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@ -31,7 +31,7 @@
#include "opt_arm_debug.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.11 2016/02/14 19:54:20 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.11.10.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -138,7 +138,8 @@ exynos_i2c_attach(device_t parent, device_t self, void *aux)
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
struct i2cbus_attach_args iba;
prop_dictionary_t devs;
uint32_t address_cells;
char intrstr[128];
bus_addr_t addr;
bus_size_t size;
@ -176,8 +177,6 @@ exynos_i2c_attach(device_t parent, device_t self, void *aux)
}
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
fdtbus_pinctrl_set_config_index(phandle, 0);
sc->sc_ic.ic_cookie = sc;
sc->sc_ic.ic_acquire_bus = exynos_i2c_acquire_bus;
sc->sc_ic.ic_release_bus = exynos_i2c_release_bus;
@ -187,7 +186,22 @@ exynos_i2c_attach(device_t parent, device_t self, void *aux)
sc->sc_ic.ic_read_byte = exynos_i2c_read_byte;
sc->sc_ic.ic_write_byte = exynos_i2c_write_byte;
fdtbus_register_i2c_controller(self, phandle, &exynos_i2c_funcs);
devs = prop_dictionary_create();
if (of_getprop_uint32(phandle, "#address-cells", &address_cells))
address_cells = 1;
of_enter_i2c_devs(devs, phandle, address_cells * 4, 0);
memset(&iba, 0, sizeof(iba));
iba.iba_tag = &sc->sc_ic;
iba.iba_child_devices = prop_dictionary_get(devs, "i2c-child-devices");
if (iba.iba_child_devices != NULL)
prop_object_retain(iba.iba_child_devices);
else
iba.iba_child_devices = prop_array_create();
prop_object_release(devs);
sc->sc_i2cdev = config_found_ia(self, "i2cbus", &iba, iicbus_print);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos_intr.h,v 1.2 2014/09/05 08:01:05 skrll Exp $ */
/* $NetBSD: exynos_intr.h,v 1.2.12.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -32,18 +32,6 @@
#ifndef _ARM_SAMSUNG_EXYNOS_INTR_H_
#define _ARM_SAMSUNG_EXYNOS_INTR_H_
#define PIC_MAXSOURCES GIC_MAXSOURCES(224)
#define PIC_MAXMAXSOURCES (PIC_MAXSOURCES + 32) /* XXX */
/*
* The Exynos uses a generic interrupt controller
*/
#include <arm/cortex/gic_intr.h>
#ifdef _KERNEL_OPT
#include "opt_exynos.h"
#endif
/*
* The GIC supports
* - 16 Software Generated Interrupts (SGIs)
@ -61,9 +49,5 @@
#define IRQ_MCT_LTIMER IRQ_PPI(12)
#ifdef EXYNOS5
#include <arm/cortex/gtmr_intr.h>
#endif
#endif /* _ARM_SAMSUNG_EXYNOS_INTR_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos_pinctrl.c,v 1.9 2016/01/01 22:37:07 marty Exp $ */
/* $NetBSD: exynos_pinctrl.c,v 1.9.10.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@ -34,7 +34,7 @@
#include "gpio.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.9 2016/01/01 22:37:07 marty Exp $");
__KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.9.10.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -55,16 +55,15 @@ __KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.9 2016/01/01 22:37:07 marty Exp
struct exynos_pinctrl_config {
int pc_phandle;
struct exynos_gpio_pin_cfg *pc_pincfg;
struct exynos_gpio_pin_cfg pc_pincfg;
struct exynos_pinctrl_softc *pc_sc;
};
static int exynos_pinctrl_match(device_t, cfdata_t, void *);
static void exynos_pinctrl_attach(device_t, device_t, void *);
static int exynos_pinctrl_set_cfg(void *);
static struct exynos_gpio_pin_cfg *
exynos_parse_config(struct exynos_pinctrl_config *pc);
static int exynos_pinctrl_set_cfg(device_t, const void *, size_t);
static void exynos_parse_config(int, struct exynos_gpio_pin_cfg *);
static struct fdtbus_pinctrl_controller_func exynos_pinctrl_controller_func = {
.set_config = exynos_pinctrl_set_cfg
@ -126,90 +125,61 @@ exynos_pinctrl_attach(device_t parent, device_t self, void *aux)
}
if (is_pinctrl(child)) {
struct exynos_pinctrl_config *pc;
pc = kmem_alloc(sizeof(*pc), KM_SLEEP);
pc->pc_phandle = child;
pc->pc_sc = sc;
pc->pc_pincfg = exynos_parse_config(pc);
fdtbus_register_pinctrl_config(pc, child,
fdtbus_register_pinctrl_config(self, child,
&exynos_pinctrl_controller_func);
}
}
fdtbus_pinctrl_configure();
}
static struct exynos_gpio_pin_cfg *
exynos_parse_config(struct exynos_pinctrl_config *pc)
static void
exynos_parse_config(int phandle, struct exynos_gpio_pin_cfg *gc)
{
struct exynos_gpio_pin_cfg *gc = kmem_zalloc(sizeof(*gc), KM_SLEEP);
int len;
int value;
len = OF_getprop(pc->pc_phandle, "samsung,pin-function",
&value, sizeof(value));
if (len > 0) {
gc->cfg = be32toh(value);
}
len = OF_getprop(pc->pc_phandle, "samsung,pin-pud", &value,
sizeof(&value));
if (len > 0) {
gc->pud = be32toh(value);
}
len = OF_getprop(pc->pc_phandle, "samsung,pin-drv", &value,
sizeof(&value));
if (len > 0) {
gc->drv = be32toh(value);
}
len = OF_getprop(pc->pc_phandle, "samsung,pin-conpwd", &value,
sizeof(&value));
if (len > 0) {
gc->conpwd = be32toh(value);
}
len = OF_getprop(pc->pc_phandle, "samsung,pin-pudpwd", &value,
sizeof(&value));
if (len > 0) {
gc->pudpwd = be32toh(value);
}
return gc;
of_getprop_uint32(phandle, "samsung,pin-function", &gc->cfg);
of_getprop_uint32(phandle, "samsung,pin-pud", &gc->pud);
of_getprop_uint32(phandle, "samsung,pin-drv", &gc->drv);
of_getprop_uint32(phandle, "samsung,pin-conpwd", &gc->conpwd);
of_getprop_uint32(phandle, "samsung,pin-pudpwd", &gc->pudpwd);
}
static int
exynos_do_config(struct exynos_pinctrl_config *pc)
{
struct exynos_gpio_pin_cfg *gc = pc->pc_pincfg;
struct exynos_gpio_pin_cfg *gc = &pc->pc_pincfg;
struct exynos_gpio_bank *bank;
int len;
char result[20];
const char *pins;
if (gc == NULL) {
printf("%s: No configuration available\n", __func__);
int pins_len = OF_getproplen(pc->pc_phandle, "samsung,pins");
if (pins_len <= 0)
return -1;
for (pins = fdtbus_get_string(pc->pc_phandle, "samsung,pins");
pins_len > 0;
pins_len -= strlen(pins) + 1, pins += strlen(pins) + 1) {
bank = exynos_gpio_bank_lookup(pins);
if (bank == NULL) {
aprint_error_dev(pc->pc_sc->sc_dev,
"unknown pin name '%s'\n", pins);
continue;
}
exynos_gpio_pin_ctl_write(bank, gc);
}
len = OF_getprop(pc->pc_phandle, "samsung,pins", result,
sizeof(result));
if (len <= 0) {
printf("%s: couldn't get pins. (%d)\n", __func__,
pc->pc_phandle);
return -1;
}
bank = exynos_gpio_bank_lookup(&result[0]);
if (!bank) {
printf("%s: Couldn't get bank \"%s\".\n", __func__, result);
return -1;
}
exynos_gpio_pin_ctl_write(bank, gc);
return 0;
}
static int
exynos_pinctrl_set_cfg(void *cookie)
exynos_pinctrl_set_cfg(device_t dev, const void *data, size_t len)
{
struct exynos_pinctrl_config *pc = cookie;
return exynos_do_config(pc);
struct exynos_pinctrl_config pc;
if (len != 4)
return -1;
pc.pc_phandle = fdtbus_get_phandle_from_native(be32dec(data));
pc.pc_sc = device_private(dev);
exynos_parse_config(pc.pc_phandle, &pc.pc_pincfg);
return exynos_do_config(&pc);
}

View File

@ -0,0 +1,161 @@
/* $NetBSD: exynos_platform.c,v 1.6.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared D. McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include "opt_exynos.h"
#include "opt_multiprocessor.h"
#include "opt_fdt_arm.h"
#include "ukbd.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exynos_platform.c,v 1.6.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <dev/fdt/fdtvar.h>
#include <uvm/uvm_extern.h>
#include <machine/bootconfig.h>
#include <arm/cpufunc.h>
#include <arm/samsung/exynos_reg.h>
#include <arm/samsung/exynos_var.h>
#include <evbarm/exynos/platform.h>
#include <arm/cortex/gtmr_var.h>
#include <arm/fdt/arm_fdtvar.h>
#define EXYNOS5_SWRESET_REG 0x10040400
#define DEVMAP_ALIGN(a) ((a) & ~L1_S_OFFSET)
#define DEVMAP_SIZE(s) roundup2((s), L1_S_SIZE)
#define DEVMAP_ENTRY(va, pa, sz) \
{ \
.pd_va = DEVMAP_ALIGN(va), \
.pd_pa = DEVMAP_ALIGN(pa), \
.pd_size = DEVMAP_SIZE(sz), \
.pd_prot = VM_PROT_READ|VM_PROT_WRITE, \
.pd_cache = PTE_NOCACHE \
}
#define DEVMAP_ENTRY_END { 0 }
static const struct pmap_devmap *
exynos_platform_devmap(void)
{
static const struct pmap_devmap devmap[] = {
DEVMAP_ENTRY(EXYNOS_CORE_VBASE,
EXYNOS_CORE_PBASE,
EXYNOS5_CORE_SIZE),
DEVMAP_ENTRY(EXYNOS5_AUDIOCORE_VBASE,
EXYNOS5_AUDIOCORE_PBASE,
EXYNOS5_AUDIOCORE_SIZE),
DEVMAP_ENTRY_END
};
return devmap;
}
#define EXYNOS_IOPHYSTOVIRT(a) \
((vaddr_t)(((a) - EXYNOS_CORE_PBASE) + EXYNOS_CORE_VBASE))
static void
exynos_platform_bootstrap(void)
{
paddr_t uart_address = armreg_tpidruro_read(); /* XXX */
exynos_bootstrap(EXYNOS_CORE_VBASE, EXYNOS_IOPHYSTOVIRT(uart_address));
}
static void
exynos_platform_init_attach_args(struct fdt_attach_args *faa)
{
extern struct bus_space armv7_generic_bs_tag;
extern struct bus_space armv7_generic_a4x_bs_tag;
extern struct arm32_bus_dma_tag armv7_generic_dma_tag;
faa->faa_bst = &armv7_generic_bs_tag;
faa->faa_a4x_bst = &armv7_generic_a4x_bs_tag;
faa->faa_dmat = &armv7_generic_dma_tag;
}
static void
exynos_platform_early_putchar(char c)
{
#if defined(VERBOSE_INIT_ARM)
extern void exynos_putchar(int); /* XXX from exynos_start.S */
exynos_putchar(c);
#endif
}
static void
exynos_platform_device_register(device_t self, void *aux)
{
exynos_device_register(self, aux);
}
static void
exynos5_platform_reset(void)
{
bus_space_tag_t bst = &armv7_generic_bs_tag;
bus_space_handle_t bsh;
bus_space_map(bst, EXYNOS5_SWRESET_REG, 4, 0, &bsh);
bus_space_write_4(bst, bsh, 0, 1);
}
static void
exynos_platform_delay(u_int us)
{
gtmr_delay(us);
}
static u_int
exynos_platform_uart_freq(void)
{
return EXYNOS_UART_FREQ;
}
static const struct arm_platform exynos5_platform = {
.devmap = exynos_platform_devmap,
.bootstrap = exynos_platform_bootstrap,
.init_attach_args = exynos_platform_init_attach_args,
.early_putchar = exynos_platform_early_putchar,
.device_register = exynos_platform_device_register,
.reset = exynos5_platform_reset,
.delay = exynos_platform_delay,
.uart_freq = exynos_platform_uart_freq,
};
ARM_PLATFORM(exynos5, "samsung,exynos5", &exynos5_platform);

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos_reg.h,v 1.13 2014/09/30 14:20:55 reinoud Exp $ */
/* $NetBSD: exynos_reg.h,v 1.13.12.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -97,10 +97,10 @@
#define EXYNOS_BLOCK_SIZE 0x00010000
#if defined(EXYNOS5)
#if defined(SOC_EXYNOS5)
#include <arm/samsung/exynos5_reg.h>
#endif
#if defined(EXYNOS4)
#if defined(SOC_EXYNOS4)
#include <arm/samsung/exynos4_reg.h>
#endif
@ -124,7 +124,8 @@
#define PLL_CON0_P __BITS( 8,13) /* PLL P divide value */
#define PLL_CON0_S __BITS( 0, 2) /* PLL S divide value */
#define PLL_PMS2FREQ(F, M, P, S) (((M)*(F))/((P)*(1<<(S))))
#define PLL_PMS2FREQ(F, M, P, S) \
((P) == 0 ? 0 : (((M)*(F))/((P)*(1<<(S)))))
#define PLL_FREQ(f, v) PLL_PMS2FREQ( \
(f),\
__SHIFTOUT((v), PLL_CON0_M),\

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos_soc.c,v 1.31 2015/12/21 04:58:50 marty Exp $ */
/* $NetBSD: exynos_soc.c,v 1.31.10.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -31,10 +31,8 @@
#include "opt_exynos.h"
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: exynos_soc.c,v 1.31 2015/12/21 04:58:50 marty Exp $");
__KERNEL_RCSID(1, "$NetBSD: exynos_soc.c,v 1.31.10.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -76,7 +74,7 @@ struct cpu_freq {
};
#ifdef EXYNOS4
#ifdef SOC_EXYNOS4
const struct cpu_freq cpu_freq_settings_exynos4[] = {
{ 200, 3, 100, 2},
{ 300, 4, 200, 2},
@ -100,7 +98,7 @@ const struct cpu_freq cpu_freq_settings_exynos4[] = {
#endif
#ifdef EXYNOS5
#ifdef SOC_EXYNOS5
#define EXYNOS5_DEFAULT_ENTRY 7
const struct cpu_freq cpu_freq_settings_exynos5[] = {
{ 200, 3, 100, 2},
@ -207,7 +205,7 @@ exynos_cpu_boot(int cpu)
}
#ifdef EXYNOS4
#ifdef SOC_EXYNOS4
/*
* The latency values used below are `magic' and probably chosen empirically.
* For the 4210 variant the data latency is lower, a 0x110. This is currently
@ -456,13 +454,13 @@ exynos_dump_clocks(void)
uint32_t freq;
printf("Initial PLL settings\n");
#ifdef EXYNOS4
#ifdef SOC_EXYNOS4
DUMP_PLL(4, APLL);
DUMP_PLL(4, MPLL);
DUMP_PLL(4, EPLL);
DUMP_PLL(4, VPLL);
#endif
#ifdef EXYNOS5
#ifdef SOC_EXYNOS5
DUMP_PLL(5, APLL);
DUMP_PLL(5, MPLL);
DUMP_PLL(5, KPLL);
@ -479,6 +477,15 @@ exynos_dump_clocks(void)
/* XXX clock stuff needs major work XXX */
void
exynos_init_clkout_for_usb(void)
{
/* Select XUSBXTI as source for CLKOUT */
bus_space_write_4(&armv7_generic_bs_tag, exynos_pmu_bsh,
EXYNOS_PMU_DEBUG_CLKOUT, 0x1000);
}
void
exynos_clocks_bootstrap(void)
{
@ -493,7 +500,7 @@ exynos_clocks_bootstrap(void)
/* set (max) cpufreq */
fsel = ncpu_freq_settings-1;
#ifdef EXYNOS5
#ifdef SOC_EXYNOS5
/* XXX BUGFIX selecting freq on E5 goes wrong for now XXX */
fsel = EXYNOS5_DEFAULT_ENTRY;
#endif
@ -524,7 +531,7 @@ exynos_bootstrap(vaddr_t iobase, vaddr_t uartbase)
printf("Exynos early console operational\n\n");
#endif
#ifdef EXYNOS4
#ifdef SOC_EXYNOS4
core_size = EXYNOS4_CORE_SIZE;
audiocore_size = EXYNOS4_AUDIOCORE_SIZE;
audiocore_pbase = EXYNOS4_AUDIOCORE_PBASE;
@ -538,7 +545,7 @@ exynos_bootstrap(vaddr_t iobase, vaddr_t uartbase)
ncpu_freq_settings = __arraycount(cpu_freq_settings_exynos4);
#endif
#ifdef EXYNOS5
#ifdef SOC_EXYNOS5
core_size = EXYNOS5_CORE_SIZE;
audiocore_size = EXYNOS5_AUDIOCORE_SIZE;
audiocore_pbase = EXYNOS5_AUDIOCORE_PBASE;
@ -594,9 +601,6 @@ exynos_bootstrap(vaddr_t iobase, vaddr_t uartbase)
panic("%s: failed to subregion cmu apll registers: %d",
__func__, error);
/* init bus dma tags */
exynos_dma_bootstrap(physmem * PAGE_SIZE);
/* gpio bootstrapping delayed */
}
@ -625,7 +629,7 @@ exynos_device_register(device_t self, void *aux)
extern uint32_t exynos_soc_id;
switch (EXYNOS_PRODUCT_ID(exynos_soc_id)) {
#ifdef EXYNOS5
#ifdef SOC_EXYNOS5
case 0xe5410:
/* offsets not changed on matt's request */
#if 0
@ -643,7 +647,7 @@ exynos_device_register(device_t self, void *aux)
break;
}
#endif
#ifdef EXYNOS4
#ifdef SOC_EXYNOS4
case 0xe4410:
case 0xe4412: {
struct mpcore_attach_args * const mpcaa = aux;
@ -661,7 +665,7 @@ exynos_device_register(device_t self, void *aux)
return;
}
if (device_is_a(self, "armgtmr") || device_is_a(self, "mct")) {
#ifdef EXYNOS5
#ifdef SOC_EXYNOS5
/*
* The global timer is dependent on the MCT running.
*/
@ -733,7 +737,7 @@ exynos_usb2_set_isolation(bool on)
}
#ifdef EXYNOS4
#ifdef SOC_EXYNOS4
static void
exynos4_usb2phy_enable(bus_space_handle_t usb2phy_bsh)
{
@ -794,7 +798,7 @@ exynos4_usb2phy_enable(bus_space_handle_t usb2phy_bsh)
#endif
#ifdef EXYNOS5
#ifdef SOC_EXYNOS5
static void
exynos5410_usb2phy_enable(bus_space_handle_t usb2phy_bsh)
{
@ -909,10 +913,10 @@ exynos_usb_phy_init(bus_space_handle_t usb2phy_bsh)
/* disable phy isolation */
exynos_usb2_set_isolation(false);
#ifdef EXYNOS4
#ifdef SOC_EXYNOS4
exynos4_usb2phy_enable(usb2phy_bsh);
#endif
#ifdef EXYNOS5
#ifdef SOC_EXYNOS5
if (IS_EXYNOS5410_P()) {
exynos5410_usb2phy_enable(usb2phy_bsh);
/* TBD: USB3 phy init */

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos_sscom.c,v 1.7 2015/12/21 00:54:35 marty Exp $ */
/* $NetBSD: exynos_sscom.c,v 1.7.10.1 2017/07/18 19:13:08 snj Exp $ */
/*
* Copyright (c) 2014 Reinoud Zandijk
@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exynos_sscom.c,v 1.7 2015/12/21 00:54:35 marty Exp $");
__KERNEL_RCSID(0, "$NetBSD: exynos_sscom.c,v 1.7.10.1 2017/07/18 19:13:08 snj Exp $");
#include "opt_sscom.h"
#include "opt_ddb.h"
@ -79,10 +79,14 @@ static void sscom_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(exynos_sscom, sizeof(struct sscom_softc), sscom_match,
sscom_attach, NULL, NULL);
static const char * const compatible[] = {
"samsung,exynos4210-uart",
NULL
};
static int
sscom_match(device_t parent, cfdata_t cf, void *aux)
{
const char * const compatible[] = { "samsung,exynos4210-uart", NULL };
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
@ -147,32 +151,46 @@ sscom_attach(device_t parent, device_t self, void *aux)
{
struct sscom_softc *sc = device_private(self);
struct fdt_attach_args *faa = aux;
int unit = -1;
const int phandle = faa->faa_phandle;
bus_space_tag_t bst = faa->faa_bst;
bus_space_handle_t bsh;
bus_space_tag_t bst;
struct clk *clk_uart, *clk_uart_baud0;
char intrstr[128];
bus_addr_t addr;
bus_size_t size;
int error;
int i;
if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
/* unit is required for the sscom driver, which desperately
* needs to be rewritten. For now, this hack gets the answer.
* MJF: FIX ME
*/
for (i = 1; i < num_exynos_uarts_entries; i += 2)
if (EXYNOS_CORE_PBASE + exynos_uarts[i] == addr)
break;
unit = exynos_uarts[i-1];
if (bus_space_map(bst, addr, size, 0, &bsh) != 0) {
aprint_error(": couldn't map registers\n");
return;
}
clk_uart = fdtbus_clock_get(phandle, "uart");
if (clk_uart != NULL) {
if (clk_enable(clk_uart) != 0) {
aprint_error(": couldn't enable uart clock\n");
return;
}
}
clk_uart_baud0 = fdtbus_clock_get(phandle, "clk_uart_baud0");
if (clk_uart_baud0 == NULL) {
aprint_error(": couldn't get baud clock\n");
return;
}
if (clk_enable(clk_uart_baud0) != 0) {
aprint_error(": couldn't enable baud clock\n");
return;
}
sc->sc_dev = self;
sc->sc_iot = bst = faa->faa_bst;
sc->sc_ioh = exynos_uarts[i] + EXYNOS_CORE_VBASE;
sc->sc_unit = unit;
sc->sc_frequency = EXYNOS_UART_FREQ;
sc->sc_ioh = bsh;
sc->sc_unit = phandle;
sc->sc_frequency = clk_get_rate(clk_uart_baud0);
sc->sc_change_txrx_interrupts = exynos_change_txrx_interrupts;
sc->sc_clear_interrupts = exynos_clear_interrupts;
@ -181,26 +199,22 @@ sscom_attach(device_t parent, device_t self, void *aux)
sc->sc_rx_irqno = 0;
sc->sc_tx_irqno = 0;
if (!sscom_is_console(sc->sc_iot, unit, &sc->sc_ioh)) {
error = bus_space_map(bst, addr, size, 0, &bsh);
if (error) {
aprint_error(": couldn't map %#llx: %d\n",
(uint64_t)addr, error);
return;
}
sc->sc_ioh = bsh;
} else {
aprint_normal(" (console) ");
}
if (sscom_is_console(sc->sc_iot, phandle, &sc->sc_ioh))
aprint_normal(" (console)");
aprint_normal("\n");
#if 0
void *ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_SERIAL,
if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
aprint_error_dev(self, "failed to decode interrupt\n");
return;
}
void *ih = fdtbus_intr_establish(phandle, 0, IPL_SERIAL,
FDT_INTR_MPSAFE, sscomintr, sc);
if (ih == NULL)
aprint_error_dev(self, "failed to establish interrupt\n");
#endif
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
sscom_attach_subr(sc);
@ -226,3 +240,56 @@ exynos_sscom_kgdb_attach(bus_space_tag_t iot, int unit, int rate,
}
#endif /* KGDB */
#endif
/*
* Console support
*/
static int
exynos_sscom_console_match(int phandle)
{
return of_match_compatible(phandle, compatible);
}
static void
exynos_sscom_console_consinit(struct fdt_attach_args *faa, u_int uart_freq)
{
const struct sscom_uart_info info = {
.iobase = 0, /* Offset from bsh */
.unit = faa->faa_phandle
};
const int phandle = faa->faa_phandle;
bus_space_tag_t bst = faa->faa_bst;
bus_space_handle_t bsh;
bus_addr_t addr;
bus_size_t size;
tcflag_t flags;
int speed;
fdtbus_get_reg(phandle, 0, &addr, &size);
speed = fdtbus_get_stdout_speed();
if (speed < 0)
speed = 115200; /* default */
flags = fdtbus_get_stdout_flags();
if (bus_space_map(bst, addr, size, 0, &bsh) != 0)
panic("cannot map console UART");
/* Calculate UART frequency from bootloader (XXX) */
uint32_t freq = speed
* (16 * (bus_space_read_4(bst, bsh, SSCOM_UBRDIV) + 1)
+ bus_space_read_4(bst, bsh, SSCOM_UFRACVAL));
freq = (freq + speed / 2) / 1000;
freq *= 1000;
if (sscom_cnattach(bst, bsh, &info, speed, freq, flags) != 0)
panic("cannot attach console UART");
}
static const struct fdt_console exynos_sscom_console = {
.match = exynos_sscom_console_match,
.consinit = exynos_sscom_console_consinit,
};
FDT_CONSOLE(exynos_sscom, &exynos_sscom_console);

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos_sysmmu.c,v 1.1 2016/01/03 04:10:58 marty Exp $ */
/* $NetBSD: exynos_sysmmu.c,v 1.1.12.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@ -34,7 +34,7 @@
#include "gpio.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: exynos_sysmmu.c,v 1.1 2016/01/03 04:10:58 marty Exp $");
__KERNEL_RCSID(1, "$NetBSD: exynos_sysmmu.c,v 1.1.12.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -102,6 +102,10 @@ exynos_sysmmu_attach(device_t parent, device_t self, void *aux)
return;
}
aprint_normal(" @ 0x%08x: SYSMMU - NOT IMPLEMENTED", (uint)addr);
aprint_naive("\n");
aprint_normal("\n");
if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
aprint_error_dev(self, "failed to decode interrupt\n");
return;
@ -116,9 +120,6 @@ exynos_sysmmu_attach(device_t parent, device_t self, void *aux)
}
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
aprint_normal(" @ 0x%08x: SYSMMU - NOT IMPLEMENTED", (uint)addr);
aprint_naive("\n");
aprint_normal("\n");
}

View File

@ -1,4 +1,4 @@
# $NetBSD: files.exynos,v 1.21 2016/01/03 04:10:58 marty Exp $
# $NetBSD: files.exynos,v 1.21.10.1 2017/07/18 19:13:08 snj Exp $
#
# Configuration info for Samsung Exynos SoC ARM Peripherals
#
@ -13,10 +13,10 @@ file arch/arm/arm32/arm32_kvminit.c
file arch/arm/arm32/arm32_reboot.c
file arch/arm/arm32/irq_dispatch.S
file arch/arm/arm32/armv7_generic_space.c
file arch/arm/arm32/armv7_generic_dma.c
file arch/arm/arm/bus_space_a4x.S
file arch/arm/samsung/exynos_soc.c
#file arch/arm/samsung/exynos_space.c
file arch/arm/samsung/exynos_smc.S arm_trustzone_firmware
# Console parameters
@ -30,23 +30,20 @@ defparam opt_exynos.h EXYNOS_WDT_DEFAULT_PERIOD
defflag opt_exynos.h EXYNOS_CONSOLE_EARLY
#
defflag opt_exynos.h EXYNOS4: CPU_CORTEXA9
defflag opt_exynos.h EXYNOS4120: EXYNOS4
defflag opt_exynos.h EXYNOS4212: EXYNOS4
defflag opt_exynos.h EXYNOS4412: EXYNOS4
defflag opt_exynos.h EXYNOS4412P: EXYNOS4
defflag opt_exynos.h EXYNOS5: CPU_CORTEXA15
defflag opt_exynos.h EXYNOS5250: EXYNOS5
defflag opt_exynos.h EXYNOS5260: EXYNOS5
defflag opt_exynos.h EXYNOS5410: EXYNOS5
defflag opt_exynos.h EXYNOS5420: EXYNOS5
defflag opt_exynos.h EXYNOS5440: EXYNOS5
defflag opt_exynos.h EXYNOS5422: EXYNOS5
defflag opt_exynos.h SOC_EXYNOS4: CPU_CORTEXA9
defflag opt_exynos.h SOC_EXYNOS4120: SOC_EXYNOS4
defflag opt_exynos.h SOC_EXYNOS4212: SOC_EXYNOS4
defflag opt_exynos.h SOC_EXYNOS4412: SOC_EXYNOS4
defflag opt_exynos.h SOC_EXYNOS4412P: SOC_EXYNOS4
defflag opt_exynos.h SOC_EXYNOS5: CPU_CORTEXA15
defflag opt_exynos.h SOC_EXYNOS5250: SOC_EXYNOS5
defflag opt_exynos.h SOC_EXYNOS5260: SOC_EXYNOS5
defflag opt_exynos.h SOC_EXYNOS5410: SOC_EXYNOS5
defflag opt_exynos.h SOC_EXYNOS5420: SOC_EXYNOS5
defflag opt_exynos.h SOC_EXYNOS5440: SOC_EXYNOS5
defflag opt_exynos.h SOC_EXYNOS5422: SOC_EXYNOS5
# On-board I/O
device exynosfdt : bus_space_generic, fdtbus
attach exynosfdt at mainbus with exynos_fdt
file arch/arm/samsung/exynos_fdt.c exynos_fdt
file arch/arm/samsung/exynos_platform.c soc_exynos5
# Interrupt combiner
device exyointr
@ -64,12 +61,12 @@ attach sysmmu at fdt with exynos_sysmmu
file arch/arm/samsung/exynos_sysmmu.c exynos_sysmmu
# real time clock
device exyortc : ftdbus
device exyortc : fdtbus
attach exyortc at fdt with exynos_rtc
file arch/arm/samsung/exynos_rtc.c exynos_rtc
# Multi Core timer
device mct : ftdbus
device mct { } : fdtbus, mpcorebus
attach mct at fdt with exyo_mct
file arch/arm/samsung/mct.c exyo_mct
@ -120,8 +117,10 @@ device exyoi2c: i2cbus, i2c_bitbang
attach exyoi2c at fdt with exynos_i2c
file arch/arm/samsung/exynos_i2c.c exynos_i2c needs-flag
file arch/arm/samsung/exynos5422_dma.c
device exy5422clk: clk
attach exy5422clk at fdt with exynos5422_clock
file arch/arm/samsung/exynos5422_clock.c exynos5422_clock
device exy5410clk: clk
attach exy5410clk at fdt with exynos5410_clock
file arch/arm/samsung/exynos5410_clock.c exynos5410_clock

View File

@ -1,4 +1,4 @@
/* $NetBSD: mct.c,v 1.10 2016/01/07 04:45:10 marty Exp $ */
/* $NetBSD: mct.c,v 1.10.10.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.10 2016/01/07 04:45:10 marty Exp $");
__KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.10.10.1 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -50,36 +50,24 @@ __KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.10 2016/01/07 04:45:10 marty Exp $");
#include <arm/samsung/mct_reg.h>
#include <arm/samsung/mct_var.h>
#include <arm/cortex/gtmr_intr.h>
#include <arm/cortex/mpcore_var.h>
#include <arm/cortex/gtmr_var.h>
#include <dev/fdt/fdtvar.h>
#include <arm/fdt/arm_fdtvar.h>
static int mct_match(device_t, cfdata_t, void *);
static void mct_attach(device_t, device_t, void *);
static int clockhandler(void *);
CFATTACH_DECL_NEW(exyo_mct, 0, mct_match, mct_attach, NULL, NULL);
#if 0
static struct timecounter mct_timecounter = {
.tc_get_timecount = mct_get_timecount,
.tc_poll_pps = 0,
.tc_counter_mask = ~0u,
.tc_frequency = 0, /* set by cpu_initclocks() */
.tc_name = NULL, /* set by cpu_initclocks() */
.tc_quality = 500, /* why 500? */
.tc_priv = &mct_sc,
.tc_next = NULL,
};
#endif
static inline uint32_t
mct_read_global(struct mct_softc *sc, bus_size_t o)
{
return bus_space_read_4(sc->sc_bst, sc->sc_bsh, o);
}
static inline void
mct_write_global(struct mct_softc *sc, bus_size_t o, uint32_t v)
{
@ -129,6 +117,12 @@ mct_write_global(struct mct_softc *sc, bus_size_t o, uint32_t v)
panic("MCT hangs after writing %#x at %#x", v, (uint32_t) o);
}
static void
mct_fdt_cpu_hatch(void *priv, struct cpu_info *ci)
{
gtmr_init_cpu_clock(ci);
}
static int
mct_match(device_t parent, cfdata_t cf, void *aux)
{
@ -139,7 +133,6 @@ mct_match(device_t parent, cfdata_t cf, void *aux)
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
mct_attach(device_t parent, device_t self, void *aux)
{
@ -157,6 +150,7 @@ mct_attach(device_t parent, device_t self, void *aux)
self->dv_private = sc;
sc->sc_dev = self;
sc->sc_bst = faa->faa_bst;
sc->sc_freq = EXYNOS_F_IN_FREQ;
error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
if (error) {
@ -166,122 +160,20 @@ mct_attach(device_t parent, device_t self, void *aux)
}
aprint_naive("\n");
aprint_normal(": Exynos SoC multi core timer (64 bits) - NOT IMPLEMENTED\n");
aprint_normal(": Exynos SoC multi core timer (64 bits)\n");
evcnt_attach_dynamic(&sc->sc_ev_missing_ticks, EVCNT_TYPE_MISC, NULL,
device_xname(self), "missing interrupts");
for (int i = 0; i < 12; i++)
fdtbus_intr_establish(faa->faa_phandle, i, 0, 0,
clockhandler, 0);
}
static inline uint64_t
mct_gettime(struct mct_softc *sc)
{
uint32_t lo, hi;
do {
hi = mct_read_global(sc, MCT_G_CNT_U);
lo = mct_read_global(sc, MCT_G_CNT_L);
} while (hi != mct_read_global(sc, MCT_G_CNT_U));
return ((uint64_t) hi << 32) | lo;
}
/* interrupt handler */
static int
clockhandler(void *arg)
{
struct clockframe * const cf = arg;
struct mct_softc * const sc = &mct_sc;
const uint64_t now = mct_gettime(sc);
int64_t delta = now - sc->sc_lastintr;
int64_t periods = delta / sc->sc_autoinc;
KASSERT(delta >= 0);
KASSERT(periods >= 0);
/* ack the interrupt */
mct_write_global(sc, MCT_G_INT_CSTAT, G_INT_CSTAT_CLEAR);
/* check if we missed clock interrupts */
if (periods > 1)
sc->sc_ev_missing_ticks.ev_count += periods - 1;
sc->sc_lastintr = now;
hardclock(cf);
/* handled */
return 1;
}
void
mct_init_cpu_clock(struct cpu_info *ci)
{
struct mct_softc * const sc = &mct_sc;
uint64_t now = mct_gettime(sc);
uint64_t then;
uint32_t tcon;
KASSERT(ci == curcpu());
sc->sc_lastintr = now;
/* get current config */
tcon = mct_read_global(sc, MCT_G_TCON);
/* setup auto increment */
mct_write_global(sc, MCT_G_COMP0_ADD_INCR, sc->sc_autoinc);
/* (re)setup comparator */
then = now + sc->sc_autoinc;
mct_write_global(sc, MCT_G_COMP0_L, (uint32_t) then);
mct_write_global(sc, MCT_G_COMP0_U, (uint32_t) (then >> 32));
tcon |= G_TCON_COMP0_AUTOINC;
tcon |= G_TCON_COMP0_ENABLE;
/* start timer */
/* Start the timer */
uint32_t tcon = mct_read_global(sc, MCT_G_TCON);
tcon |= G_TCON_START;
/* enable interrupt */
mct_write_global(sc, MCT_G_INT_ENB, G_INT_ENB_ENABLE);
/* update config, starting the thing */
mct_write_global(sc, MCT_G_TCON, tcon);
/* Attach ARMv7 generic timer */
struct mpcore_attach_args mpcaa = {
.mpcaa_name = "armgtmr",
.mpcaa_irq = IRQ_GTMR_PPI_VTIMER
};
config_found(self, &mpcaa, NULL);
arm_fdt_cpu_hatch_register(self, mct_fdt_cpu_hatch);
}
#if 0
void
cpu_initclocks(void)
{
struct mct_softc * const sc = &mct_sc;
sc->sc_autoinc = sc->sc_freq / hz;
mct_init_cpu_clock(curcpu());
mct_timecounter.tc_name = device_xname(sc->sc_dev);
mct_timecounter.tc_frequency = sc->sc_freq;
tc_init(&mct_timecounter);
#if 0
{
uint64_t then, now;
printf("testing timer\n");
for (int i = 0; i < 200; i++) {
printf("cstat %d\n", mct_read_global(sc, MCT_G_INT_CSTAT));
then = mct_get_timecount(&mct_timecounter);
do {
now = mct_get_timecount(&mct_timecounter);
} while (now == then);
printf("\tgot %"PRIu64"\n", now);
for (int j = 0; j < 90000; j++);
}
printf("passed\n");
}
#endif
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: mct_var.h,v 1.4 2015/12/21 00:54:35 marty Exp $ */
/* $NetBSD: mct_var.h,v 1.4.10.1 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -52,6 +52,7 @@ static struct mct_softc {
} mct_sc;
void mct_init_cpu_clock(struct cpu_info *ci);
void mct_delay(u_int);
#endif /* _ARM_SAMSUNG_MCT_VAR_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sscom.c,v 1.8 2015/04/13 21:18:41 riastradh Exp $ */
/* $NetBSD: sscom.c,v 1.8.10.1 2017/07/18 19:13:08 snj Exp $ */
/*
* Copyright (c) 2002, 2003 Fujitsu Component Limited
@ -98,7 +98,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sscom.c,v 1.8 2015/04/13 21:18:41 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: sscom.c,v 1.8.10.1 2017/07/18 19:13:08 snj Exp $");
#include "opt_sscom.h"
#include "opt_ddb.h"
@ -179,13 +179,9 @@ static int sscom_to_tiocm(struct sscom_softc *);
static void sscom_iflush(struct sscom_softc *);
static int sscomhwiflow(struct tty *tp, int block);
#if defined(KGDB) || \
defined(SSCOM0CONSOLE) || defined(SSCOM1CONSOLE) || \
defined(SSCOM2CONSOLE) || defined(SSCOM3CONSOLE)
static int sscom_init(bus_space_tag_t, bus_space_handle_t,
const struct sscom_uart_info *,
int, int, tcflag_t, bus_space_handle_t *);
#endif
extern struct cfdriver sscom_cd;
@ -1836,9 +1832,6 @@ sscomintr(void *v)
}
#if defined(KGDB) || \
defined(SSCOM0CONSOLE) || defined(SSCOM1CONSOLE) || \
defined(SSCOM2CONSOLE) || defined(SSCOM3CONSOLE)
/*
* Initialize UART for use as console or KGDB line.
*/
@ -1882,11 +1875,6 @@ sscom_init(bus_space_tag_t iot, bus_space_handle_t base_ioh,
return 0;
}
#endif
#if \
defined(SSCOM0CONSOLE) || defined(SSCOM1CONSOLE) || \
defined(SSCOM2CONSOLE) || defined(SSCOM3CONSOLE)
/*
* Following are all routines needed for SSCOM to act as console
*/
@ -2024,8 +2012,6 @@ sscomcnpollc(dev_t dev, int on)
sscom_readaheadcount = 0;
}
#endif /* SSCOM0CONSOLE||SSCOM1CONSOLE */
#ifdef KGDB
int
sscom_kgdb_attach(bus_space_tag_t iot, bus_space_handle_t ioh,

View File

@ -0,0 +1,110 @@
# $NetBSD: files.sunxi,v 1.12.4.2 2017/07/18 19:13:08 snj Exp $
#
# Configuration info for Allwinner sunxi family SoCs
#
#
include "arch/arm/pic/files.pic"
include "arch/arm/cortex/files.cortex"
file arch/arm/arm32/arm32_boot.c
file arch/arm/arm32/arm32_kvminit.c
file arch/arm/arm32/arm32_reboot.c
file arch/arm/arm32/irq_dispatch.S
file arch/arm/arm32/armv7_generic_space.c
file arch/arm/arm32/armv7_generic_dma.c
file arch/arm/arm/bus_space_a4x.S
file arch/arm/sunxi/sunxi_platform.c soc_sunxi
# CCU
define sunxi_ccu
file arch/arm/sunxi/sunxi_ccu.c sunxi_ccu
file arch/arm/sunxi/sunxi_ccu_div.c sunxi_ccu
file arch/arm/sunxi/sunxi_ccu_gate.c sunxi_ccu
file arch/arm/sunxi/sunxi_ccu_nm.c sunxi_ccu
file arch/arm/sunxi/sunxi_ccu_nkmp.c sunxi_ccu
file arch/arm/sunxi/sunxi_ccu_prediv.c sunxi_ccu
# CCU (A31)
device sun6ia31ccu: sunxi_ccu
attach sun6ia31ccu at fdt with sunxi_a31_ccu
file arch/arm/sunxi/sun6i_a31_ccu.c sunxi_a31_ccu
# CCU (A83T)
device sun8ia83tccu: sunxi_ccu
attach sun8ia83tccu at fdt with sunxi_a83t_ccu
file arch/arm/sunxi/sun8i_a83t_ccu.c sunxi_a83t_ccu
# CCU (H3)
device sun8ih3ccu: sunxi_ccu
attach sun8ih3ccu at fdt with sunxi_h3_ccu
file arch/arm/sunxi/sun8i_h3_ccu.c sunxi_h3_ccu
# Misc. clock resets
device sunxiresets
attach sunxiresets at fdt with sunxi_resets
file arch/arm/sunxi/sunxi_resets.c sunxi_resets
# Misc. clock gates
device sunxigates
attach sunxigates at fdt with sunxi_gates
file arch/arm/sunxi/sunxi_gates.c sunxi_gates
# GPIO
device sunxigpio: gpiobus
attach sunxigpio at fdt with sunxi_gpio
file arch/arm/sunxi/sunxi_gpio.c sunxi_gpio
file arch/arm/sunxi/sun6i_a31_gpio.c sunxi_gpio & soc_sun6i_a31
file arch/arm/sunxi/sun8i_a83t_gpio.c sunxi_gpio & soc_sun8i_a83t
file arch/arm/sunxi/sun8i_h3_gpio.c sunxi_gpio & soc_sun8i_h3
# UART
attach com at fdt with sunxi_com
file arch/arm/sunxi/sunxi_com.c sunxi_com needs-flag
# SD/MMC
device sunximmc: sdmmcbus
attach sunximmc at fdt with sunxi_mmc
file arch/arm/sunxi/sunxi_mmc.c sunxi_mmc
# USB PHY
device sunxiusbphy
attach sunxiusbphy at fdt with sunxi_usbphy
file arch/arm/sunxi/sunxi_usbphy.c sunxi_usbphy
# EHCI
attach ehci at fdt with ehci_fdt
file dev/fdt/ehci_fdt.c ehci_fdt
# OHCI
attach ohci at fdt with ohci_fdt
file dev/fdt/ohci_fdt.c ohci_fdt
# TWI
device sunxitwi: i2cbus, i2cexec, mvi2c
attach sunxitwi at fdt with sunxi_twi
file arch/arm/sunxi/sunxi_twi.c sunxi_twi
# P2WI/RSB
device sunxirsb: i2cbus, i2cexec
attach sunxirsb at fdt with sunxi_rsb
file arch/arm/sunxi/sunxi_rsb.c sunxi_rsb
# RTC
device sunxirtc
attach sunxirtc at fdt with sunxi_rtc
file arch/arm/sunxi/sunxi_rtc.c sunxi_rtc
# EMAC
device sunxiemac: arp, ether, ifnet, mii
attach sunxiemac at fdt with sunxi_emac
file arch/arm/sunxi/sunxi_emac.c sunxi_emac
# SOC parameters
defflag opt_soc.h SOC_SUNXI
defflag opt_soc.h SOC_SUN8I: SOC_SUNXI
defflag opt_soc.h SOC_SUN8I_A83T: SOC_SUN8I
defflag opt_soc.h SOC_SUN8I_H3: SOC_SUN8I
defflag opt_soc.h SOC_SUN6I: SOC_SUNXI
defflag opt_soc.h SOC_SUN6I_A31: SOC_SUN6I

View File

@ -0,0 +1,280 @@
/* $NetBSD: sun6i_a31_ccu.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* Copyright (c) 2017 Emmanuel Vadot <manu@freebsd.org>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: sun6i_a31_ccu.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <dev/fdt/fdtvar.h>
#include <arm/sunxi/sunxi_ccu.h>
#include <arm/sunxi/sun6i_a31_ccu.h>
#define PLL_PERIPH_CTRL_REG 0x028
#define AHB1_APB1_CFG_REG 0x054
#define APB2_CLK_DIV_REG 0x058
#define AHB1_GATING_REG0 0x060
#define AHB1_GATING_REG1 0x064
#define APB1_GATING_REG 0x068
#define APB2_GATING_REG 0x06c
#define SD0_CLK_REG 0x088
#define SD1_CLK_REG 0x08c
#define SD2_CLK_REG 0x090
#define SD3_CLK_REG 0x094
#define USBPHY_CFG_REG 0x0cc
#define BUS_SOFT_RST_REG0 0x2c0
#define BUS_SOFT_RST_REG1 0x2c4
#define BUS_SOFT_RST_REG2 0x2c8
#define BUS_SOFT_RST_REG3 0x2d0
#define BUS_SOFT_RST_REG4 0x2d8
static int sun6i_a31_ccu_match(device_t, cfdata_t, void *);
static void sun6i_a31_ccu_attach(device_t, device_t, void *);
static const char * const compatible[] = {
"allwinner,sun6i-a31-ccu",
NULL
};
CFATTACH_DECL_NEW(sunxi_a31_ccu, sizeof(struct sunxi_ccu_softc),
sun6i_a31_ccu_match, sun6i_a31_ccu_attach, NULL, NULL);
static struct sunxi_ccu_reset sun6i_a31_ccu_resets[] = {
SUNXI_CCU_RESET(A31_RST_USB_PHY0, USBPHY_CFG_REG, 0),
SUNXI_CCU_RESET(A31_RST_USB_PHY1, USBPHY_CFG_REG, 1),
SUNXI_CCU_RESET(A31_RST_USB_PHY2, USBPHY_CFG_REG, 2),
SUNXI_CCU_RESET(A31_RST_AHB1_MIPI_DSI, BUS_SOFT_RST_REG0, 1),
SUNXI_CCU_RESET(A31_RST_AHB1_SS, BUS_SOFT_RST_REG0, 5),
SUNXI_CCU_RESET(A31_RST_AHB1_DMA, BUS_SOFT_RST_REG0, 6),
SUNXI_CCU_RESET(A31_RST_AHB1_MMC0, BUS_SOFT_RST_REG0, 8),
SUNXI_CCU_RESET(A31_RST_AHB1_MMC1, BUS_SOFT_RST_REG0, 9),
SUNXI_CCU_RESET(A31_RST_AHB1_MMC2, BUS_SOFT_RST_REG0, 10),
SUNXI_CCU_RESET(A31_RST_AHB1_MMC3, BUS_SOFT_RST_REG0, 11),
SUNXI_CCU_RESET(A31_RST_AHB1_NAND1, BUS_SOFT_RST_REG0, 12),
SUNXI_CCU_RESET(A31_RST_AHB1_NAND0, BUS_SOFT_RST_REG0, 13),
SUNXI_CCU_RESET(A31_RST_AHB1_SDRAM, BUS_SOFT_RST_REG0, 14),
SUNXI_CCU_RESET(A31_RST_AHB1_EMAC, BUS_SOFT_RST_REG0, 17),
SUNXI_CCU_RESET(A31_RST_AHB1_TS, BUS_SOFT_RST_REG0, 18),
SUNXI_CCU_RESET(A31_RST_AHB1_HSTIMER, BUS_SOFT_RST_REG0, 19),
SUNXI_CCU_RESET(A31_RST_AHB1_SPI0, BUS_SOFT_RST_REG0, 20),
SUNXI_CCU_RESET(A31_RST_AHB1_SPI1, BUS_SOFT_RST_REG0, 21),
SUNXI_CCU_RESET(A31_RST_AHB1_SPI2, BUS_SOFT_RST_REG0, 22),
SUNXI_CCU_RESET(A31_RST_AHB1_SPI3, BUS_SOFT_RST_REG0, 23),
SUNXI_CCU_RESET(A31_RST_AHB1_OTG, BUS_SOFT_RST_REG0, 24),
SUNXI_CCU_RESET(A31_RST_AHB1_EHCI0, BUS_SOFT_RST_REG0, 26),
SUNXI_CCU_RESET(A31_RST_AHB1_EHCI1, BUS_SOFT_RST_REG0, 27),
SUNXI_CCU_RESET(A31_RST_AHB1_OHCI0, BUS_SOFT_RST_REG0, 29),
SUNXI_CCU_RESET(A31_RST_AHB1_OHCI1, BUS_SOFT_RST_REG0, 30),
SUNXI_CCU_RESET(A31_RST_AHB1_OHCI2, BUS_SOFT_RST_REG0, 31),
SUNXI_CCU_RESET(A31_RST_AHB1_VE, BUS_SOFT_RST_REG1, 0),
SUNXI_CCU_RESET(A31_RST_AHB1_LCD0, BUS_SOFT_RST_REG1, 4),
SUNXI_CCU_RESET(A31_RST_AHB1_LCD1, BUS_SOFT_RST_REG1, 5),
SUNXI_CCU_RESET(A31_RST_AHB1_CSI, BUS_SOFT_RST_REG1, 8),
SUNXI_CCU_RESET(A31_RST_AHB1_HDMI, BUS_SOFT_RST_REG1, 11),
SUNXI_CCU_RESET(A31_RST_AHB1_BE0, BUS_SOFT_RST_REG1, 12),
SUNXI_CCU_RESET(A31_RST_AHB1_BE1, BUS_SOFT_RST_REG1, 13),
SUNXI_CCU_RESET(A31_RST_AHB1_FE0, BUS_SOFT_RST_REG1, 14),
SUNXI_CCU_RESET(A31_RST_AHB1_FE1, BUS_SOFT_RST_REG1, 15),
SUNXI_CCU_RESET(A31_RST_AHB1_MP, BUS_SOFT_RST_REG1, 16),
SUNXI_CCU_RESET(A31_RST_AHB1_GPU, BUS_SOFT_RST_REG1, 20),
SUNXI_CCU_RESET(A31_RST_AHB1_DEU0, BUS_SOFT_RST_REG1, 23),
SUNXI_CCU_RESET(A31_RST_AHB1_DEU1, BUS_SOFT_RST_REG1, 24),
SUNXI_CCU_RESET(A31_RST_AHB1_DRC0, BUS_SOFT_RST_REG1, 25),
SUNXI_CCU_RESET(A31_RST_AHB1_DRC1, BUS_SOFT_RST_REG1, 26),
SUNXI_CCU_RESET(A31_RST_AHB1_LVDS, BUS_SOFT_RST_REG2, 0),
SUNXI_CCU_RESET(A31_RST_APB1_CODEC, BUS_SOFT_RST_REG3, 0),
SUNXI_CCU_RESET(A31_RST_APB1_SPDIF, BUS_SOFT_RST_REG3, 1),
SUNXI_CCU_RESET(A31_RST_APB1_DIGITAL_MIC, BUS_SOFT_RST_REG3, 4),
SUNXI_CCU_RESET(A31_RST_APB1_DAUDIO0, BUS_SOFT_RST_REG3, 12),
SUNXI_CCU_RESET(A31_RST_APB1_DAUDIO1, BUS_SOFT_RST_REG3, 13),
SUNXI_CCU_RESET(A31_RST_APB2_I2C0, BUS_SOFT_RST_REG4, 0),
SUNXI_CCU_RESET(A31_RST_APB2_I2C1, BUS_SOFT_RST_REG4, 1),
SUNXI_CCU_RESET(A31_RST_APB2_I2C2, BUS_SOFT_RST_REG4, 2),
SUNXI_CCU_RESET(A31_RST_APB2_I2C3, BUS_SOFT_RST_REG4, 3),
SUNXI_CCU_RESET(A31_RST_APB2_UART0, BUS_SOFT_RST_REG4, 16),
SUNXI_CCU_RESET(A31_RST_APB2_UART1, BUS_SOFT_RST_REG4, 17),
SUNXI_CCU_RESET(A31_RST_APB2_UART2, BUS_SOFT_RST_REG4, 18),
SUNXI_CCU_RESET(A31_RST_APB2_UART3, BUS_SOFT_RST_REG4, 19),
SUNXI_CCU_RESET(A31_RST_APB2_UART4, BUS_SOFT_RST_REG4, 20),
SUNXI_CCU_RESET(A31_RST_APB2_UART5, BUS_SOFT_RST_REG4, 21),
};
static const char *ahb1_parents[] = { "losc", "hosc", "axi", "pll_periph" };
static const char *apb1_parents[] = { "ahb1" };
static const char *apb2_parents[] = { "losc", "hosc", "pll_periph", "pll_periph" };
static const char *mod_parents[] = { "hosc", "pll_periph" };
static struct sunxi_ccu_clk sun6i_a31_ccu_clks[] = {
SUNXI_CCU_NKMP(A31_CLK_PLL_PERIPH, "pll_periph", "hosc",
PLL_PERIPH_CTRL_REG, /* reg */
__BITS(12,8), /* n */
__BITS(5,4), /* k */
0, /* m */
0, /* p */
__BIT(31), /* enable */
SUNXI_CCU_NKMP_DIVIDE_BY_TWO),
SUNXI_CCU_DIV(A31_CLK_APB1, "apb1", apb1_parents,
AHB1_APB1_CFG_REG, /* reg */
__BITS(9,8), /* div */
0, /* sel */
SUNXI_CCU_DIV_POWER_OF_TWO|SUNXI_CCU_DIV_ZERO_IS_ONE),
SUNXI_CCU_PREDIV(A31_CLK_AHB1, "ahb1", ahb1_parents,
AHB1_APB1_CFG_REG, /* reg */
__BITS(7,6), /* prediv */
__BIT(3), /* prediv_sel */
__BITS(5,4), /* div */
__BITS(13,12), /* sel */
SUNXI_CCU_PREDIV_POWER_OF_TWO),
SUNXI_CCU_NM(A31_CLK_APB2, "apb2", apb2_parents,
APB2_CLK_DIV_REG, /* reg */
__BITS(17,16), /* n */
__BITS(4,0), /* m */
__BITS(25,24), /* sel */
0, /* enable */
SUNXI_CCU_NM_POWER_OF_TWO),
SUNXI_CCU_NM(A31_CLK_MMC0, "mmc0", mod_parents,
SD0_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
SUNXI_CCU_NM(A31_CLK_MMC1, "mmc1", mod_parents,
SD1_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
SUNXI_CCU_NM(A31_CLK_MMC2, "mmc2", mod_parents,
SD2_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
SUNXI_CCU_NM(A31_CLK_MMC3, "mmc3", mod_parents,
SD3_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
SUNXI_CCU_GATE(A31_CLK_AHB1_MMC0, "ahb1-mmc0", "ahb1",
AHB1_GATING_REG0, 8),
SUNXI_CCU_GATE(A31_CLK_AHB1_MMC1, "ahb1-mmc1", "ahb1",
AHB1_GATING_REG0, 9),
SUNXI_CCU_GATE(A31_CLK_AHB1_MMC2, "ahb1-mmc2", "ahb1",
AHB1_GATING_REG0, 10),
SUNXI_CCU_GATE(A31_CLK_AHB1_MMC3, "ahb1-mmc3", "ahb1",
AHB1_GATING_REG0, 11),
SUNXI_CCU_GATE(A31_CLK_AHB1_EMAC, "ahb1-emac", "ahb1",
AHB1_GATING_REG0, 17),
SUNXI_CCU_GATE(A31_CLK_AHB1_OTG, "ahb1-otg", "ahb1",
AHB1_GATING_REG0, 24),
SUNXI_CCU_GATE(A31_CLK_AHB1_EHCI0, "ahb1-ehci0", "ahb1",
AHB1_GATING_REG0, 26),
SUNXI_CCU_GATE(A31_CLK_AHB1_EHCI1, "ahb1-ehci1", "ahb1",
AHB1_GATING_REG0, 27),
SUNXI_CCU_GATE(A31_CLK_AHB1_OHCI0, "ahb1-ohci0", "ahb1",
AHB1_GATING_REG0, 29),
SUNXI_CCU_GATE(A31_CLK_AHB1_OHCI1, "ahb1-ohci1", "ahb1",
AHB1_GATING_REG0, 30),
SUNXI_CCU_GATE(A31_CLK_AHB1_OHCI2, "ahb1-ohci2", "ahb1",
AHB1_GATING_REG0, 31),
SUNXI_CCU_GATE(A31_CLK_APB1_PIO, "ahb1-pio", "apb1",
APB1_GATING_REG, 5),
SUNXI_CCU_GATE(A31_CLK_APB2_I2C0, "apb2-i2c0", "apb2",
APB2_GATING_REG, 0),
SUNXI_CCU_GATE(A31_CLK_APB2_I2C1, "apb2-i2c1", "apb2",
APB2_GATING_REG, 1),
SUNXI_CCU_GATE(A31_CLK_APB2_I2C2, "apb2-i2c2", "apb2",
APB2_GATING_REG, 2),
SUNXI_CCU_GATE(A31_CLK_APB2_I2C3, "apb2-i2c3", "apb2",
APB2_GATING_REG, 3),
SUNXI_CCU_GATE(A31_CLK_APB2_UART0, "apb2-uart0", "apb2",
APB2_GATING_REG, 16),
SUNXI_CCU_GATE(A31_CLK_APB2_UART1, "apb2-uart1", "apb2",
APB2_GATING_REG, 17),
SUNXI_CCU_GATE(A31_CLK_APB2_UART2, "apb2-uart2", "apb2",
APB2_GATING_REG, 18),
SUNXI_CCU_GATE(A31_CLK_APB2_UART3, "apb2-uart3", "apb2",
APB2_GATING_REG, 19),
SUNXI_CCU_GATE(A31_CLK_APB2_UART4, "apb2-uart4", "apb2",
APB2_GATING_REG, 20),
SUNXI_CCU_GATE(A31_CLK_APB2_UART5, "apb2-uart5", "apb2",
APB2_GATING_REG, 21),
SUNXI_CCU_GATE(A31_CLK_USB_PHY0, "usb-phy0", "hosc",
USBPHY_CFG_REG, 8),
SUNXI_CCU_GATE(A31_CLK_USB_PHY1, "usb-phy1", "hosc",
USBPHY_CFG_REG, 9),
SUNXI_CCU_GATE(A31_CLK_USB_PHY2, "usb-phy2", "hosc",
USBPHY_CFG_REG, 10),
SUNXI_CCU_GATE(A31_CLK_USB_OHCI0, "usb-ohci0", "hosc",
USBPHY_CFG_REG, 16),
SUNXI_CCU_GATE(A31_CLK_USB_OHCI1, "usb-ohci1", "hosc",
USBPHY_CFG_REG, 17),
SUNXI_CCU_GATE(A31_CLK_USB_OHCI2, "usb-ohci2", "hosc",
USBPHY_CFG_REG, 18),
};
static int
sun6i_a31_ccu_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
sun6i_a31_ccu_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_ccu_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
sc->sc_dev = self;
sc->sc_phandle = faa->faa_phandle;
sc->sc_bst = faa->faa_bst;
sc->sc_resets = sun6i_a31_ccu_resets;
sc->sc_nresets = __arraycount(sun6i_a31_ccu_resets);
sc->sc_clks = sun6i_a31_ccu_clks;
sc->sc_nclks = __arraycount(sun6i_a31_ccu_clks);
if (sunxi_ccu_attach(sc) != 0)
return;
aprint_naive("\n");
aprint_normal(": A31 CCU\n");
sunxi_ccu_print(sc);
}

View File

@ -0,0 +1,250 @@
/* $NetBSD: sun6i_a31_ccu.h,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Emmanuel Vadot <manu@freebsd.org>
* 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 ``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 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 __CCU_A31_H__
#define __CCU_A31_H__
#define A31_RST_USB_PHY0 0
#define A31_RST_USB_PHY1 1
#define A31_RST_USB_PHY2 2
#define A31_RST_AHB1_MIPI_DSI 3
#define A31_RST_AHB1_SS 4
#define A31_RST_AHB1_DMA 5
#define A31_RST_AHB1_MMC0 6
#define A31_RST_AHB1_MMC1 7
#define A31_RST_AHB1_MMC2 8
#define A31_RST_AHB1_MMC3 9
#define A31_RST_AHB1_NAND1 10
#define A31_RST_AHB1_NAND0 11
#define A31_RST_AHB1_SDRAM 12
#define A31_RST_AHB1_EMAC 13
#define A31_RST_AHB1_TS 14
#define A31_RST_AHB1_HSTIMER 15
#define A31_RST_AHB1_SPI0 16
#define A31_RST_AHB1_SPI1 17
#define A31_RST_AHB1_SPI2 18
#define A31_RST_AHB1_SPI3 19
#define A31_RST_AHB1_OTG 20
#define A31_RST_AHB1_EHCI0 21
#define A31_RST_AHB1_EHCI1 22
#define A31_RST_AHB1_OHCI0 23
#define A31_RST_AHB1_OHCI1 24
#define A31_RST_AHB1_OHCI2 25
#define A31_RST_AHB1_VE 26
#define A31_RST_AHB1_LCD0 27
#define A31_RST_AHB1_LCD1 28
#define A31_RST_AHB1_CSI 29
#define A31_RST_AHB1_HDMI 30
#define A31_RST_AHB1_BE0 31
#define A31_RST_AHB1_BE1 32
#define A31_RST_AHB1_FE0 33
#define A31_RST_AHB1_FE1 34
#define A31_RST_AHB1_MP 35
#define A31_RST_AHB1_GPU 36
#define A31_RST_AHB1_DEU0 37
#define A31_RST_AHB1_DEU1 38
#define A31_RST_AHB1_DRC0 39
#define A31_RST_AHB1_DRC1 40
#define A31_RST_AHB1_LVDS 41
#define A31_RST_APB1_CODEC 42
#define A31_RST_APB1_SPDIF 43
#define A31_RST_APB1_DIGITAL_MIC 44
#define A31_RST_APB1_DAUDIO0 45
#define A31_RST_APB1_DAUDIO1 46
#define A31_RST_APB2_I2C0 47
#define A31_RST_APB2_I2C1 48
#define A31_RST_APB2_I2C2 49
#define A31_RST_APB2_I2C3 50
#define A31_RST_APB2_UART0 51
#define A31_RST_APB2_UART1 52
#define A31_RST_APB2_UART2 53
#define A31_RST_APB2_UART3 54
#define A31_RST_APB2_UART4 55
#define A31_RST_APB2_UART5 56
#define A31_CLK_PLL_CPU 0
#define A31_CLK_PLL_AUDIO_BASE 1
#define A31_CLK_PLL_AUDIO 2
#define A31_CLK_PLL_AUDIO_2X 3
#define A31_CLK_PLL_AUDIO_4X 4
#define A31_CLK_PLL_AUDIO_8X 5
#define A31_CLK_PLL_VIDEO0 6
#define A31_CLK_PLL_VIDEO0_2X 7
#define A31_CLK_PLL_VE 8
#define A31_CLK_PLL_DDR 9
#define A31_CLK_PLL_PERIPH 10
#define A31_CLK_PLL_PERIPH_2X 11
#define A31_CLK_PLL_VIDEO1 12
#define A31_CLK_PLL_VIDEO1_2X 13
#define A31_CLK_PLL_GPU 14
#define A31_CLK_PLL_MIPI 15
#define A31_CLK_PLL9 16
#define A31_CLK_PLL10 17
#define A31_CLK_CPU 18
#define A31_CLK_AXI 19
#define A31_CLK_AHB1 20
#define A31_CLK_APB1 21
#define A31_CLK_APB2 22
#define A31_CLK_AHB1_MIPIDSI 23
#define A31_CLK_AHB1_SS 24
#define A31_CLK_AHB1_DMA 25
#define A31_CLK_AHB1_MMC0 26
#define A31_CLK_AHB1_MMC1 27
#define A31_CLK_AHB1_MMC2 28
#define A31_CLK_AHB1_MMC3 29
#define A31_CLK_AHB1_NAND1 30
#define A31_CLK_AHB1_NAND0 31
#define A31_CLK_AHB1_SDRAM 32
#define A31_CLK_AHB1_EMAC 33
#define A31_CLK_AHB1_TS 34
#define A31_CLK_AHB1_HSTIMER 35
#define A31_CLK_AHB1_SPI0 36
#define A31_CLK_AHB1_SPI1 37
#define A31_CLK_AHB1_SPI2 38
#define A31_CLK_AHB1_SPI3 39
#define A31_CLK_AHB1_OTG 40
#define A31_CLK_AHB1_EHCI0 41
#define A31_CLK_AHB1_EHCI1 42
#define A31_CLK_AHB1_OHCI0 43
#define A31_CLK_AHB1_OHCI1 44
#define A31_CLK_AHB1_OHCI2 45
#define A31_CLK_AHB1_VE 46
#define A31_CLK_AHB1_LCD0 47
#define A31_CLK_AHB1_LCD1 48
#define A31_CLK_AHB1_CSI 49
#define A31_CLK_AHB1_HDMI 50
#define A31_CLK_AHB1_BE0 51
#define A31_CLK_AHB1_BE1 52
#define A31_CLK_AHB1_FE0 53
#define A31_CLK_AHB1_FE1 54
#define A31_CLK_AHB1_MP 55
#define A31_CLK_AHB1_GPU 56
#define A31_CLK_AHB1_DEU0 57
#define A31_CLK_AHB1_DEU1 58
#define A31_CLK_AHB1_DRC0 59
#define A31_CLK_AHB1_DRC1 60
#define A31_CLK_APB1_CODEC 61
#define A31_CLK_APB1_SPDIF 62
#define A31_CLK_APB1_DIGITAL_MIC 63
#define A31_CLK_APB1_PIO 64
#define A31_CLK_APB1_DAUDIO0 65
#define A31_CLK_APB1_DAUDIO1 66
#define A31_CLK_APB2_I2C0 67
#define A31_CLK_APB2_I2C1 68
#define A31_CLK_APB2_I2C2 69
#define A31_CLK_APB2_I2C3 70
#define A31_CLK_APB2_UART0 71
#define A31_CLK_APB2_UART1 72
#define A31_CLK_APB2_UART2 73
#define A31_CLK_APB2_UART3 74
#define A31_CLK_APB2_UART4 75
#define A31_CLK_APB2_UART5 76
#define A31_CLK_NAND0 77
#define A31_CLK_NAND1 78
#define A31_CLK_MMC0 79
#define A31_CLK_MMC0_SAMPLE 80
#define A31_CLK_MMC0_OUTPUT 81
#define A31_CLK_MMC1 82
#define A31_CLK_MMC1_SAMPLE 83
#define A31_CLK_MMC1_OUTPUT 84
#define A31_CLK_MMC2 85
#define A31_CLK_MMC2_SAMPLE 86
#define A31_CLK_MMC2_OUTPUT 87
#define A31_CLK_MMC3 88
#define A31_CLK_MMC3_SAMPLE 89
#define A31_CLK_MMC3_OUTPUT 90
#define A31_CLK_TS 91
#define A31_CLK_SS 92
#define A31_CLK_SPI0 93
#define A31_CLK_SPI1 94
#define A31_CLK_SPI2 95
#define A31_CLK_SPI3 96
#define A31_CLK_DAUDIO0 97
#define A31_CLK_DAUDIO1 98
#define A31_CLK_SPDIF 99
#define A31_CLK_USB_PHY0 100
#define A31_CLK_USB_PHY1 101
#define A31_CLK_USB_PHY2 102
#define A31_CLK_USB_OHCI0 103
#define A31_CLK_USB_OHCI1 104
#define A31_CLK_USB_OHCI2 105
#define A31_CLK_MDFS 107
#define A31_CLK_SDRAM0 108
#define A31_CLK_SDRAM1 109
#define A31_CLK_DRAM_VE 110
#define A31_CLK_DRAM_CSI_ISP 111
#define A31_CLK_DRAM_TS 112
#define A31_CLK_DRAM_DRC0 113
#define A31_CLK_DRAM_DRC1 114
#define A31_CLK_DRAM_DEU0 115
#define A31_CLK_DRAM_DEU1 116
#define A31_CLK_DRAM_FE0 117
#define A31_CLK_DRAM_FE1 118
#define A31_CLK_DRAM_BE0 119
#define A31_CLK_DRAM_BE1 120
#define A31_CLK_DRAM_MP 121
#define A31_CLK_BE0 122
#define A31_CLK_BE1 123
#define A31_CLK_FE0 124
#define A31_CLK_FE1 125
#define A31_CLK_MP 126
#define A31_CLK_LCD0_CH0 127
#define A31_CLK_LCD1_CH0 128
#define A31_CLK_LCD0_CH1 129
#define A31_CLK_LCD1_CH1 130
#define A31_CLK_CSI0_SCLK 131
#define A31_CLK_CSI0_MCLK 132
#define A31_CLK_CSI1_MCLK 133
#define A31_CLK_VE 134
#define A31_CLK_CODEC 135
#define A31_CLK_AVS 136
#define A31_CLK_DIGITAL_MIC 137
#define A31_CLK_HDMI 138
#define A31_CLK_HDMI_DDC 139
#define A31_CLK_PS 140
#define A31_CLK_MBUS0 141
#define A31_CLK_MBUS1 142
#define A31_CLK_MIPI_DSI 143
#define A31_CLK_MIPI_DSI_DPHY 144
#define A31_CLK_MIPI_CSI_DPHY 145
#define A31_CLK_IEP_DRC0 146
#define A31_CLK_IEP_DRC1 147
#define A31_CLK_IEP_DEU0 148
#define A31_CLK_IEP_DEU1 149
#define A31_CLK_GPU_CORE 150
#define A31_CLK_GPU_MEMORY 151
#define A31_CLK_GPU_HYD 152
#define A31_CLK_ATS 153
#define A31_CLK_TRACE 154
#define A31_CLK_OUT_A 155
#define A31_CLK_OUT_B 156
#define A31_CLK_OUT_C 157
#endif /* __CCU_A31 H__ */

View File

@ -0,0 +1,244 @@
/* $NetBSD: sun6i_a31_gpio.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2016 Emmanuel Vadot <manu@freebsd.org>
* 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.
*
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sun6i_a31_gpio.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/types.h>
#include <arm/sunxi/sunxi_gpio.h>
static const struct sunxi_gpio_pins a31_pins[] = {
{"PA0", 0, 0, {"gpio_in", "gpio_out", "gmac", "lcd1", "uart1", NULL, "pa_eint0", NULL}, 6, 0},
{"PA1", 0, 1, {"gpio_in", "gpio_out", "gmac", "lcd1", "uart1", NULL, "pa_eint1", NULL}, 6, 1},
{"PA2", 0, 2, {"gpio_in", "gpio_out", "gmac", "lcd1", "uart1", NULL, "pa_eint2", NULL}, 6, 2},
{"PA3", 0, 3, {"gpio_in", "gpio_out", "gmac", "lcd1", "uart1", NULL, "pa_eint3", NULL}, 6, 3},
{"PA4", 0, 4, {"gpio_in", "gpio_out", "gmac", "lcd1", "uart1", NULL, "pa_eint4", NULL}, 6, 4},
{"PA5", 0, 5, {"gpio_in", "gpio_out", "gmac", "lcd1", "uart1", NULL, "pa_eint5", NULL}, 6, 5},
{"PA6", 0, 6, {"gpio_in", "gpio_out", "gmac", "lcd1", "uart1", NULL, "pa_eint6", NULL}, 6, 6},
{"PA7", 0, 7, {"gpio_in", "gpio_out", "gmac", "lcd1", "uart1", NULL, "pa_eint7", NULL}, 6, 7},
{"PA8", 0, 8, {"gpio_in", "gpio_out", "gmac", "lcd1", NULL, NULL, "pa_eint8", NULL}, 6, 8},
{"PA9", 0, 9, {"gpio_in", "gpio_out", "gmac", "lcd1", NULL, "mmc2", "pa_eint9", NULL}, 6, 9},
{"PA10", 0, 10, {"gpio_in", "gpio_out", "gmac", "lcd1", "mmc3", "mmc2", "pa_eint10", NULL}, 6, 10},
{"PA11", 0, 11, {"gpio_in", "gpio_out", "gmac", "lcd1", "mmc3", "mmc2", "pa_eint11", NULL}, 6, 11},
{"PA12", 0, 12, {"gpio_in", "gpio_out", "gmac", "lcd1", "mmc3", "mmc2", "pa_eint12", NULL}, 6, 12},
{"PA13", 0, 13, {"gpio_in", "gpio_out", "gmac", "lcd1", "mmc3", "mmc2", "pa_eint13", NULL}, 6, 13},
{"PA14", 0, 14, {"gpio_in", "gpio_out", "gmac", "lcd1", "mmc3", "mmc2", "pa_eint14", NULL}, 6, 14},
{"PA15", 0, 15, {"gpio_in", "gpio_out", "gmac", "lcd1", "clk_out_a", NULL, "pa_eint15", NULL}, 6, 15},
{"PA16", 0, 16, {"gpio_in", "gpio_out", "gmac", "lcd1", "dmic", NULL, "pa_eint16", NULL}, 6, 16},
{"PA17", 0, 17, {"gpio_in", "gpio_out", "gmac", "lcd1", "dmic", NULL, "pa_eint17", NULL}, 6, 17},
{"PA18", 0, 18, {"gpio_in", "gpio_out", "gmac", "lcd1", "clk_out_b", NULL, "pa_eint18", NULL}, 6, 18},
{"PA19", 0, 19, {"gpio_in", "gpio_out", "gmac", "lcd1", "pwm3", NULL, "pa_eint19", NULL}, 6, 19},
{"PA20", 0, 20, {"gpio_in", "gpio_out", "gmac", "lcd1", "pwm3", NULL, "pa_eint20", NULL}, 6, 20},
{"PA21", 0, 21, {"gpio_in", "gpio_out", "gmac", "lcd1", "spi3", NULL, "pa_eint21", NULL}, 6, 21},
{"PA22", 0, 22, {"gpio_in", "gpio_out", "gmac", "lcd1", "spi3", NULL, "pa_eint22", NULL}, 6, 22},
{"PA23", 0, 23, {"gpio_in", "gpio_out", "gmac", "lcd1", "spi3", NULL, "pa_eint23", NULL}, 6, 23},
{"PA24", 0, 24, {"gpio_in", "gpio_out", "gmac", "lcd1", "spi3", NULL, "pa_eint24", NULL}, 6, 24},
{"PA25", 0, 25, {"gpio_in", "gpio_out", "gmac", "lcd1", "spi3", NULL, "pa_eint25", NULL}, 6, 25},
{"PA26", 0, 26, {"gpio_in", "gpio_out", "gmac", "lcd1", "clk_out_c", NULL, "pa_eint26", NULL}, 6, 26},
{"PA27", 0, 27, {"gpio_in", "gpio_out", "gmac", "lcd1", NULL, NULL, "pa_eint27", NULL}, 6, 27},
{"PB0", 1, 0, {"gpio_in", "gpio_out", "i2s0", "uart3", "csi", NULL, "pb_eint0", NULL}, 6, 0},
{"PB1", 1, 1, {"gpio_in", "gpio_out", "i2s0", NULL, NULL, NULL, "pb_eint1", NULL}, 6, 1},
{"PB2", 1, 2, {"gpio_in", "gpio_out", "i2s0", NULL, NULL, NULL, "pb_eint2", NULL}, 6, 2},
{"PB3", 1, 3, {"gpio_in", "gpio_out", "i2s0", NULL, NULL, NULL, "pb_eint3", NULL}, 6, 3},
{"PB4", 1, 4, {"gpio_in", "gpio_out", "i2s0", "uart3", NULL, NULL, "pb_eint4", NULL}, 6, 4},
{"PB5", 1, 5, {"gpio_in", "gpio_out", "i2s0", "uart3", "i2c3", NULL, "pb_eint5", NULL}, 6, 5},
{"PB6", 1, 6, {"gpio_in", "gpio_out", "i2s0", "uart3", "i2c3", NULL, "pb_eint6", NULL}, 6, 6},
{"PB7", 1, 7, {"gpio_in", "gpio_out", "i2s0", NULL, NULL, NULL, "pb_eint7", NULL}, 6, 7},
{"PC0", 2, 0, {"gpio_in", "gpio_out", "nand0", "spi0", NULL, NULL, NULL, NULL}},
{"PC1", 2, 1, {"gpio_in", "gpio_out", "nand0", "spi0", NULL, NULL, NULL, NULL}},
{"PC2", 2, 2, {"gpio_in", "gpio_out", "nand0", "spi0", NULL, NULL, NULL, NULL}},
{"PC3", 2, 3, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
{"PC4", 2, 4, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
{"PC5", 2, 5, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
{"PC6", 2, 6, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC7", 2, 7, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC8", 2, 8, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC9", 2, 9, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC10", 2, 10, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC11", 2, 11, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC12", 2, 12, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC13", 2, 13, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC14", 2, 14, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC15", 2, 15, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC16", 2, 16, {"gpio_in", "gpio_out", "nand0", "nand1", NULL, NULL, NULL, NULL}},
{"PC17", 2, 17, {"gpio_in", "gpio_out", "nand0", "nand1", NULL, NULL, NULL, NULL}},
{"PC18", 2, 18, {"gpio_in", "gpio_out", "nand0", "nand1", NULL, NULL, NULL, NULL}},
{"PC19", 2, 19, {"gpio_in", "gpio_out", "nand0", "nand1", NULL, NULL, NULL, NULL}},
{"PC20", 2, 20, {"gpio_in", "gpio_out", "nand0", "nand1", NULL, NULL, NULL, NULL}},
{"PC21", 2, 21, {"gpio_in", "gpio_out", "nand0", "nand1", NULL, NULL, NULL, NULL}},
{"PC22", 2, 22, {"gpio_in", "gpio_out", "nand0", "nand1", NULL, NULL, NULL, NULL}},
{"PC23", 2, 23, {"gpio_in", "gpio_out", "nand0", "nand1", NULL, NULL, NULL, NULL}},
{"PC24", 2, 24, {"gpio_in", "gpio_out", "nand0", "mmc2", "mmc3", NULL, NULL, NULL}},
{"PC25", 2, 25, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
{"PC26", 2, 26, {"gpio_in", "gpio_out", "nand0", NULL, NULL, NULL, NULL, NULL}},
{"PC27", 2, 27, {"gpio_in", "gpio_out", NULL, "spi0",NULL, NULL, NULL, NULL}},
{"PD0", 3, 0, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
{"PD1", 3, 1, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
{"PD2", 3, 2, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
{"PD3", 3, 3, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
{"PD4", 3, 4, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
{"PD5", 3, 5, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
{"PD6", 3, 6, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
{"PD7", 3, 7, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
{"PD8", 3, 8, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
{"PD9", 3, 9, {"gpio_in", "gpio_out", "lcd0", "lvds0", NULL, NULL, NULL, NULL}},
{"PD10", 3, 10, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
{"PD11", 3, 11, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
{"PD12", 3, 12, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
{"PD13", 3, 13, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
{"PD14", 3, 14, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
{"PD15", 3, 15, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
{"PD16", 3, 16, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
{"PD17", 3, 17, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
{"PD18", 3, 18, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
{"PD19", 3, 19, {"gpio_in", "gpio_out", "lcd0", "lvds1", NULL, NULL, NULL, NULL}},
{"PD20", 3, 20, {"gpio_in", "gpio_out", "lcd0", NULL, NULL, NULL, NULL, NULL}},
{"PD21", 3, 21, {"gpio_in", "gpio_out", "lcd0", NULL, NULL, NULL, NULL, NULL}},
{"PD22", 3, 22, {"gpio_in", "gpio_out", "lcd0", NULL, NULL, NULL, NULL, NULL}},
{"PD23", 3, 23, {"gpio_in", "gpio_out", "lcd0", NULL, NULL, NULL, NULL, NULL}},
{"PD24", 3, 24, {"gpio_in", "gpio_out", "lcd0", NULL, NULL, NULL, NULL, NULL}},
{"PD25", 3, 25, {"gpio_in", "gpio_out", "lcd0", NULL, NULL, NULL, NULL, NULL}},
{"PD26", 3, 26, {"gpio_in", "gpio_out", "lcd0", NULL, NULL, NULL, NULL, NULL}},
{"PD27", 3, 27, {"gpio_in", "gpio_out", "lcd0", NULL, NULL, NULL, NULL, NULL}},
{"PE0", 4, 0, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint0", NULL}, 6, 0},
{"PE1", 4, 1, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint1", NULL}, 6, 1},
{"PE2", 4, 2, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint2", NULL}, 6, 2},
{"PE3", 4, 3, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint3", NULL}, 6, 3},
{"PE4", 4, 4, {"gpio_in", "gpio_out", "csi", "uart5", NULL, NULL, "pe_eint4", NULL}, 6, 4},
{"PE5", 4, 5, {"gpio_in", "gpio_out", "csi", "uart5", NULL, NULL, "pe_eint5", NULL}, 6, 5},
{"PE6", 4, 6, {"gpio_in", "gpio_out", "csi", "uart5", NULL, NULL, "pe_eint6", NULL}, 6, 6},
{"PE7", 4, 7, {"gpio_in", "gpio_out", "csi", "uart5", NULL, NULL, "pe_eint7", NULL}, 6, 7},
{"PE8", 4, 8, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint8", NULL}, 6, 8},
{"PE9", 4, 9, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint9", NULL}, 6, 9},
{"PE10", 4, 10, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint10", NULL}, 6, 10},
{"PE11", 4, 11, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint11", NULL}, 6, 11},
{"PE12", 4, 12, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint12", NULL}, 6, 12},
{"PE13", 4, 13, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint13", NULL}, 6, 13},
{"PE14", 4, 14, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint14", NULL}, 6, 14},
{"PE15", 4, 15, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, "pe_eint15", NULL}, 6, 15},
{"PE16", 4, 16, {"gpio_in", "gpio_out", "csi", NULL, NULL, NULL, "pe_eint16", NULL}, 6, 16},
{"PF0", 5, 0, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
{"PF1", 5, 1, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
{"PF2", 5, 2, {"gpio_in", "gpio_out", "mmc0", NULL, "uart0", NULL, NULL, NULL}},
{"PF3", 5, 3, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
{"PF4", 5, 4, {"gpio_in", "gpio_out", "mmc0", NULL, "uart0", NULL, NULL, NULL}},
{"PF5", 5, 5, {"gpio_in", "gpio_out", "mmc0", NULL, "jtag", NULL, NULL, NULL}},
{"PG0", 6, 0, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint0", NULL}, 6, 0},
{"PG1", 6, 1, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint1", NULL}, 6, 1},
{"PG2", 6, 2, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint2", NULL}, 6, 2},
{"PG3", 6, 3, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint3", NULL}, 6, 3},
{"PG4", 6, 4, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint4", NULL}, 6, 4},
{"PG5", 6, 5, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint5", NULL}, 6, 5},
{"PG6", 6, 6, {"gpio_in", "gpio_out", "uart2", NULL, NULL, NULL, "pg_eint6", NULL}, 6, 6},
{"PG7", 6, 7, {"gpio_in", "gpio_out", "uart2", NULL, NULL, NULL, "pg_eint7", NULL}, 6, 7},
{"PG8", 6, 8, {"gpio_in", "gpio_out", "uart2", NULL, NULL, NULL, "pg_eint8", NULL}, 6, 8},
{"PG9", 6, 9, {"gpio_in", "gpio_out", "uart2", NULL, NULL, NULL, "pg_eint9", NULL}, 6, 9},
{"PG10", 6, 10, {"gpio_in", "gpio_out", "i2c3", "usb", NULL, NULL, "pg_eint10", NULL}, 6, 10},
{"PG11", 6, 11, {"gpio_in", "gpio_out", "i2c3", "usb", NULL, NULL, "pg_eint11", NULL}, 6, 11},
{"PG12", 6, 12, {"gpio_in", "gpio_out", "spi1", "i2s1", NULL, NULL, "pg_eint12", NULL}, 6, 12},
{"PG13", 6, 13, {"gpio_in", "gpio_out", "spi1", "i2s1", NULL, NULL, "pg_eint13", NULL}, 6, 13},
{"PG14", 6, 14, {"gpio_in", "gpio_out", "spi1", "i2s1", NULL, NULL, "pg_eint14", NULL}, 6, 14},
{"PG15", 6, 15, {"gpio_in", "gpio_out", "spi1", "i2s1", NULL, NULL, "pg_eint15", NULL}, 6, 15},
{"PG16", 6, 16, {"gpio_in", "gpio_out", "spi1", "i2s1", NULL, NULL, "pg_eint16", NULL}, 6, 16},
{"PG17", 6, 17, {"gpio_in", "gpio_out", "uart4", NULL, NULL, NULL, "pg_eint17", NULL}, 6, 17},
{"PG18", 6, 18, {"gpio_in", "gpio_out", "uart4", NULL, NULL, NULL, "pg_eint18", NULL}, 6, 18},
{"PH0", 7, 0, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
{"PH1", 7, 1, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
{"PH2", 7, 2, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
{"PH3", 7, 3, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
{"PH4", 7, 4, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
{"PH5", 7, 5, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
{"PH6", 7, 6, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
{"PH7", 7, 7, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
{"PH8", 7, 8, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
{"PH9", 7, 9, {"gpio_in", "gpio_out", "spi2", "jtag", "pwm1", NULL, NULL, NULL}},
{"PH10", 7, 10, {"gpio_in", "gpio_out", "spi2", "jtag", "pwm1", NULL, NULL, NULL}},
{"PH11", 7, 11, {"gpio_in", "gpio_out", "spi2", "jtag", "pwm2", NULL, NULL, NULL}},
{"PH12", 7, 12, {"gpio_in", "gpio_out", "spi2", "jtag", "pwm2", NULL, NULL, NULL}},
{"PH13", 7, 13, {"gpio_in", "gpio_out", "pwm0", NULL, NULL, NULL, NULL, NULL}},
{"PH14", 7, 14, {"gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, NULL, NULL}},
{"PH15", 7, 15, {"gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, NULL, NULL}},
{"PH16", 7, 16, {"gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, NULL, NULL}},
{"PH17", 7, 17, {"gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, NULL, NULL}},
{"PH18", 7, 18, {"gpio_in", "gpio_out", "i2c2", NULL, NULL, NULL, NULL, NULL}},
{"PH19", 7, 19, {"gpio_in", "gpio_out", "i2c2", NULL, NULL, NULL, NULL, NULL}},
{"PH20", 7, 20, {"gpio_in", "gpio_out", "uart0", NULL, NULL, NULL, NULL, NULL}},
{"PH21", 7, 21, {"gpio_in", "gpio_out", "uart0", NULL, NULL, NULL, NULL, NULL}},
{"PH22", 7, 22, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
{"PH23", 7, 23, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
{"PH24", 7, 24, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
{"PH25", 7, 25, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
{"PH26", 7, 26, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
{"PH27", 7, 27, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
{"PH28", 7, 28, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
{"PH29", 7, 29, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
{"PH30", 7, 30, {"gpio_in", "gpio_out", "nand1", NULL, NULL, NULL, NULL, NULL}},
};
static const struct sunxi_gpio_pins a31_r_pins[] = {
{"PL0", 0, 0, {"gpio_in", "gpio_out", "s_twi", "s_p2wi", NULL, NULL, NULL, NULL}},
{"PL1", 0, 1, {"gpio_in", "gpio_out", "s_twi", "s_p2wi", NULL, NULL, NULL, NULL}},
{"PL2", 0, 2, {"gpio_in", "gpio_out", "s_uart", NULL, NULL, NULL, NULL, NULL}},
{"PL3", 0, 3, {"gpio_in", "gpio_out", "s_uart", NULL, NULL, NULL, NULL, NULL}},
{"PL4", 0, 4, {"gpio_in", "gpio_out", "s_ir", NULL, NULL, NULL, NULL, NULL}},
{"PL5", 0, 5, {"gpio_in", "gpio_out", "pl_eint0", "s_jtag", NULL, NULL, NULL, NULL}, 2, 0},
{"PL6", 0, 6, {"gpio_in", "gpio_out", "pl_eint1", "s_jtag", NULL, NULL, NULL, NULL}, 2, 1},
{"PL7", 0, 7, {"gpio_in", "gpio_out", "pl_eint2", "s_jtag", NULL, NULL, NULL, NULL}, 2, 2},
{"PL8", 0, 8, {"gpio_in", "gpio_out", "pl_eint3", "s_jtag", NULL, NULL, NULL, NULL}, 2, 3},
{"PM0", 1, 0, {"gpio_in", "gpio_out", "pm_eint0", NULL, NULL, NULL, NULL, NULL}, 2, 0},
{"PM1", 1, 1, {"gpio_in", "gpio_out", "pm_eint1", NULL, NULL, NULL, NULL, NULL}, 2, 1},
{"PM2", 1, 2, {"gpio_in", "gpio_out", "pm_eint2", "1wire", NULL, NULL, NULL, NULL}, 2, 2},
{"PM3", 1, 3, {"gpio_in", "gpio_out", "pm_eint3", NULL, NULL, NULL, NULL, NULL}, 2, 3},
{"PM4", 1, 4, {"gpio_in", "gpio_out", "pm_eint4", NULL, NULL, NULL, NULL, NULL}, 2, 4},
{"PM5", 1, 5, {"gpio_in", "gpio_out", "pm_eint5", NULL, NULL, NULL, NULL, NULL}, 2, 5},
{"PM6", 1, 6, {"gpio_in", "gpio_out", "pm_eint6", NULL, NULL, NULL, NULL, NULL}, 2, 6},
{"PM7", 1, 7, {"gpio_in", "gpio_out", "pm_eint7", "rtc", NULL, NULL, NULL, NULL}, 2, 7},
};
const struct sunxi_gpio_padconf sun6i_a31_padconf = {
.npins = __arraycount(a31_pins),
.pins = a31_pins,
};
const struct sunxi_gpio_padconf sun6i_a31_r_padconf = {
.npins = __arraycount(a31_r_pins),
.pins = a31_r_pins,
};

View File

@ -0,0 +1,285 @@
/* $NetBSD: sun8i_a83t_ccu.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* Copyright (c) 2017 Emmanuel Vadot <manu@freebsd.org>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: sun8i_a83t_ccu.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <dev/fdt/fdtvar.h>
#include <arm/sunxi/sunxi_ccu.h>
#include <arm/sunxi/sun8i_a83t_ccu.h>
#define PLL_PERIPH0_CTRL_REG 0x028
#define AHB1_APB1_CFG_REG 0x054
#define APB2_CFG_REG 0x058
#define BUS_CLK_GATING_REG0 0x060
#define BUS_CLK_GATING_REG2 0x068
#define BUS_CLK_GATING_REG3 0x06c
#define SDMMC0_CLK_REG 0x088
#define SDMMC1_CLK_REG 0x08c
#define SDMMC2_CLK_REG 0x090
#define USBPHY_CFG_REG 0x0cc
#define MBUS_RST_REG 0x0fc
#define BUS_SOFT_RST_REG0 0x2c0
#define BUS_SOFT_RST_REG1 0x2c4
#define BUS_SOFT_RST_REG2 0x2c8
#define BUS_SOFT_RST_REG3 0x2d0
#define BUS_SOFT_RST_REG4 0x2d8
static int sun8i_a83t_ccu_match(device_t, cfdata_t, void *);
static void sun8i_a83t_ccu_attach(device_t, device_t, void *);
static const char * const compatible[] = {
"allwinner,sun8i-a83t-ccu",
NULL
};
CFATTACH_DECL_NEW(sunxi_a83t_ccu, sizeof(struct sunxi_ccu_softc),
sun8i_a83t_ccu_match, sun8i_a83t_ccu_attach, NULL, NULL);
static struct sunxi_ccu_reset sun8i_a83t_ccu_resets[] = {
SUNXI_CCU_RESET(H3_RST_USB_PHY0, USBPHY_CFG_REG, 0),
SUNXI_CCU_RESET(H3_RST_USB_PHY1, USBPHY_CFG_REG, 1),
SUNXI_CCU_RESET(H3_RST_USB_PHY2, USBPHY_CFG_REG, 2),
SUNXI_CCU_RESET(H3_RST_USB_PHY3, USBPHY_CFG_REG, 3),
SUNXI_CCU_RESET(H3_RST_MBUS, MBUS_RST_REG, 31),
SUNXI_CCU_RESET(H3_RST_BUS_CE, BUS_SOFT_RST_REG0, 5),
SUNXI_CCU_RESET(H3_RST_BUS_DMA, BUS_SOFT_RST_REG0, 6),
SUNXI_CCU_RESET(H3_RST_BUS_MMC0, BUS_SOFT_RST_REG0, 8),
SUNXI_CCU_RESET(H3_RST_BUS_MMC1, BUS_SOFT_RST_REG0, 9),
SUNXI_CCU_RESET(H3_RST_BUS_MMC2, BUS_SOFT_RST_REG0, 10),
SUNXI_CCU_RESET(H3_RST_BUS_NAND, BUS_SOFT_RST_REG0, 13),
SUNXI_CCU_RESET(H3_RST_BUS_DRAM, BUS_SOFT_RST_REG0, 14),
SUNXI_CCU_RESET(H3_RST_BUS_EMAC, BUS_SOFT_RST_REG0, 17),
SUNXI_CCU_RESET(H3_RST_BUS_TS, BUS_SOFT_RST_REG0, 18),
SUNXI_CCU_RESET(H3_RST_BUS_HSTIMER, BUS_SOFT_RST_REG0, 19),
SUNXI_CCU_RESET(H3_RST_BUS_SPI0, BUS_SOFT_RST_REG0, 20),
SUNXI_CCU_RESET(H3_RST_BUS_SPI1, BUS_SOFT_RST_REG0, 21),
SUNXI_CCU_RESET(H3_RST_BUS_OTG, BUS_SOFT_RST_REG0, 23),
SUNXI_CCU_RESET(H3_RST_BUS_EHCI0, BUS_SOFT_RST_REG0, 24),
SUNXI_CCU_RESET(H3_RST_BUS_EHCI1, BUS_SOFT_RST_REG0, 25),
SUNXI_CCU_RESET(H3_RST_BUS_EHCI2, BUS_SOFT_RST_REG0, 26),
SUNXI_CCU_RESET(H3_RST_BUS_EHCI3, BUS_SOFT_RST_REG0, 27),
SUNXI_CCU_RESET(H3_RST_BUS_OHCI0, BUS_SOFT_RST_REG0, 28),
SUNXI_CCU_RESET(H3_RST_BUS_OHCI1, BUS_SOFT_RST_REG0, 29),
SUNXI_CCU_RESET(H3_RST_BUS_OHCI2, BUS_SOFT_RST_REG0, 30),
SUNXI_CCU_RESET(H3_RST_BUS_OHCI3, BUS_SOFT_RST_REG0, 31),
SUNXI_CCU_RESET(H3_RST_BUS_VE, BUS_SOFT_RST_REG1, 0),
SUNXI_CCU_RESET(H3_RST_BUS_TCON0, BUS_SOFT_RST_REG1, 3),
SUNXI_CCU_RESET(H3_RST_BUS_TCON1, BUS_SOFT_RST_REG1, 4),
SUNXI_CCU_RESET(H3_RST_BUS_DEINTERLACE, BUS_SOFT_RST_REG1, 5),
SUNXI_CCU_RESET(H3_RST_BUS_CSI, BUS_SOFT_RST_REG1, 8),
SUNXI_CCU_RESET(H3_RST_BUS_TVE, BUS_SOFT_RST_REG1, 9),
SUNXI_CCU_RESET(H3_RST_BUS_HDMI0, BUS_SOFT_RST_REG1, 10),
SUNXI_CCU_RESET(H3_RST_BUS_HDMI1, BUS_SOFT_RST_REG1, 11),
SUNXI_CCU_RESET(H3_RST_BUS_DE, BUS_SOFT_RST_REG1, 12),
SUNXI_CCU_RESET(H3_RST_BUS_GPU, BUS_SOFT_RST_REG1, 20),
SUNXI_CCU_RESET(H3_RST_BUS_MSGBOX, BUS_SOFT_RST_REG1, 21),
SUNXI_CCU_RESET(H3_RST_BUS_SPINLOCK, BUS_SOFT_RST_REG1, 22),
SUNXI_CCU_RESET(H3_RST_BUS_DBG, BUS_SOFT_RST_REG1, 31),
SUNXI_CCU_RESET(H3_RST_BUS_EPHY, BUS_SOFT_RST_REG2, 2),
SUNXI_CCU_RESET(H3_RST_BUS_CODEC, BUS_SOFT_RST_REG3, 0),
SUNXI_CCU_RESET(H3_RST_BUS_SPDIF, BUS_SOFT_RST_REG3, 1),
SUNXI_CCU_RESET(H3_RST_BUS_THS, BUS_SOFT_RST_REG3, 8),
SUNXI_CCU_RESET(H3_RST_BUS_I2S0, BUS_SOFT_RST_REG3, 12),
SUNXI_CCU_RESET(H3_RST_BUS_I2S1, BUS_SOFT_RST_REG3, 13),
SUNXI_CCU_RESET(H3_RST_BUS_I2S2, BUS_SOFT_RST_REG3, 14),
SUNXI_CCU_RESET(H3_RST_BUS_I2C0, BUS_SOFT_RST_REG4, 0),
SUNXI_CCU_RESET(H3_RST_BUS_I2C1, BUS_SOFT_RST_REG4, 1),
SUNXI_CCU_RESET(H3_RST_BUS_I2C2, BUS_SOFT_RST_REG4, 2),
SUNXI_CCU_RESET(H3_RST_BUS_UART0, BUS_SOFT_RST_REG4, 16),
SUNXI_CCU_RESET(H3_RST_BUS_UART1, BUS_SOFT_RST_REG4, 17),
SUNXI_CCU_RESET(H3_RST_BUS_UART2, BUS_SOFT_RST_REG4, 18),
SUNXI_CCU_RESET(H3_RST_BUS_UART3, BUS_SOFT_RST_REG4, 19),
SUNXI_CCU_RESET(H3_RST_BUS_SCR, BUS_SOFT_RST_REG4, 20),
};
static const char *ahb1_parents[] = { "losc", "hosc", "pll_periph" };
static const char *ahb2_parents[] = { "ahb1", "pll_periph" };
static const char *apb1_parents[] = { "ahb1" };
static const char *apb2_parents[] = { "losc", "hosc", "pll_periph" };
static const char *mod_parents[] = { "hosc", "pll_periph" };
static struct sunxi_ccu_clk sun8i_a83t_ccu_clks[] = {
SUNXI_CCU_NKMP(H3_CLK_PLL_PERIPH0, "pll_periph", "hosc",
PLL_PERIPH0_CTRL_REG, /* reg */
__BITS(15,8), /* n */
0, /* k */
__BIT(18), /* m */
__BIT(16), /* p */
__BIT(31), /* enable */
SUNXI_CCU_NKMP_FACTOR_N_EXACT),
SUNXI_CCU_PREDIV(H3_CLK_AHB1, "ahb1", ahb1_parents,
AHB1_APB1_CFG_REG, /* reg */
__BITS(7,6), /* prediv */
__BIT(3), /* prediv_sel */
__BITS(5,4), /* div */
__BITS(13,12), /* sel */
SUNXI_CCU_PREDIV_POWER_OF_TWO),
SUNXI_CCU_PREDIV(H3_CLK_AHB2, "ahb2", ahb2_parents,
APB2_CFG_REG, /* reg */
0, /* prediv */
__BIT(1), /* prediv_sel */
0, /* div */
__BITS(1,0), /* sel */
SUNXI_CCU_PREDIV_DIVIDE_BY_TWO),
SUNXI_CCU_DIV(H3_CLK_APB1, "apb1", apb1_parents,
AHB1_APB1_CFG_REG, /* reg */
__BITS(9,8), /* div */
0, /* sel */
SUNXI_CCU_DIV_POWER_OF_TWO|SUNXI_CCU_DIV_ZERO_IS_ONE),
SUNXI_CCU_NM(H3_CLK_APB2, "apb2", apb2_parents,
APB2_CFG_REG, /* reg */
__BITS(17,16), /* n */
__BITS(4,0), /* m */
__BITS(25,24), /* sel */
0, /* enable */
SUNXI_CCU_NM_POWER_OF_TWO),
SUNXI_CCU_NM(H3_CLK_MMC0, "mmc0", mod_parents,
SDMMC0_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
SUNXI_CCU_NM(H3_CLK_MMC1, "mmc1", mod_parents,
SDMMC1_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
SUNXI_CCU_NM(H3_CLK_MMC2, "mmc2", mod_parents,
SDMMC2_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
SUNXI_CCU_GATE(H3_CLK_BUS_MMC0, "bus-mmc0", "ahb1",
BUS_CLK_GATING_REG0, 8),
SUNXI_CCU_GATE(H3_CLK_BUS_MMC1, "bus-mmc1", "ahb1",
BUS_CLK_GATING_REG0, 9),
SUNXI_CCU_GATE(H3_CLK_BUS_MMC2, "bus-mmc2", "ahb1",
BUS_CLK_GATING_REG0, 10),
SUNXI_CCU_GATE(H3_CLK_BUS_EMAC, "bus-emac", "ahb2",
BUS_CLK_GATING_REG0, 17),
SUNXI_CCU_GATE(H3_CLK_BUS_OTG, "bus-otg", "ahb1",
BUS_CLK_GATING_REG0, 23),
SUNXI_CCU_GATE(H3_CLK_BUS_EHCI0, "bus-ehci0", "ahb1",
BUS_CLK_GATING_REG0, 24),
SUNXI_CCU_GATE(H3_CLK_BUS_EHCI1, "bus-ehci1", "ahb2",
BUS_CLK_GATING_REG0, 25),
SUNXI_CCU_GATE(H3_CLK_BUS_EHCI2, "bus-ehci2", "ahb2",
BUS_CLK_GATING_REG0, 26),
SUNXI_CCU_GATE(H3_CLK_BUS_EHCI3, "bus-ehci3", "ahb2",
BUS_CLK_GATING_REG0, 27),
SUNXI_CCU_GATE(H3_CLK_BUS_OHCI0, "bus-ohci0", "ahb1",
BUS_CLK_GATING_REG0, 28),
SUNXI_CCU_GATE(H3_CLK_BUS_OHCI1, "bus-ohci1", "ahb2",
BUS_CLK_GATING_REG0, 29),
SUNXI_CCU_GATE(H3_CLK_BUS_OHCI2, "bus-ohci2", "ahb2",
BUS_CLK_GATING_REG0, 30),
SUNXI_CCU_GATE(H3_CLK_BUS_OHCI3, "bus-ohci3", "ahb2",
BUS_CLK_GATING_REG0, 31),
SUNXI_CCU_GATE(H3_CLK_BUS_PIO, "bus-pio", "apb1",
BUS_CLK_GATING_REG2, 5),
SUNXI_CCU_GATE(H3_CLK_BUS_I2C0, "bus-i2c0", "apb2",
BUS_CLK_GATING_REG3, 0),
SUNXI_CCU_GATE(H3_CLK_BUS_I2C1, "bus-i2c1", "apb2",
BUS_CLK_GATING_REG3, 1),
SUNXI_CCU_GATE(H3_CLK_BUS_I2C2, "bus-i2c2", "apb2",
BUS_CLK_GATING_REG3, 2),
SUNXI_CCU_GATE(H3_CLK_BUS_UART0, "bus-uart0", "apb2",
BUS_CLK_GATING_REG3, 16),
SUNXI_CCU_GATE(H3_CLK_BUS_UART1, "bus-uart1", "apb2",
BUS_CLK_GATING_REG3, 17),
SUNXI_CCU_GATE(H3_CLK_BUS_UART2, "bus-uart2", "apb2",
BUS_CLK_GATING_REG3, 18),
SUNXI_CCU_GATE(H3_CLK_BUS_UART3, "bus-uart3", "apb2",
BUS_CLK_GATING_REG3, 19),
SUNXI_CCU_GATE(H3_CLK_USBPHY0, "usb-phy0", "hosc",
USBPHY_CFG_REG, 8),
SUNXI_CCU_GATE(H3_CLK_USBPHY1, "usb-phy1", "hosc",
USBPHY_CFG_REG, 9),
SUNXI_CCU_GATE(H3_CLK_USBPHY2, "usb-phy2", "hosc",
USBPHY_CFG_REG, 10),
SUNXI_CCU_GATE(H3_CLK_USBPHY3, "usb-phy3", "hosc",
USBPHY_CFG_REG, 11),
SUNXI_CCU_GATE(H3_CLK_USBOHCI0, "usb-ohci0", "hosc",
USBPHY_CFG_REG, 16),
SUNXI_CCU_GATE(H3_CLK_USBOHCI1, "usb-ohci1", "hosc",
USBPHY_CFG_REG, 17),
SUNXI_CCU_GATE(H3_CLK_USBOHCI2, "usb-ohci2", "hosc",
USBPHY_CFG_REG, 18),
SUNXI_CCU_GATE(H3_CLK_USBOHCI3, "usb-ohci3", "hosc",
USBPHY_CFG_REG, 19),
};
static int
sun8i_a83t_ccu_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
sun8i_a83t_ccu_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_ccu_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
sc->sc_dev = self;
sc->sc_phandle = faa->faa_phandle;
sc->sc_bst = faa->faa_bst;
sc->sc_resets = sun8i_a83t_ccu_resets;
sc->sc_nresets = __arraycount(sun8i_a83t_ccu_resets);
sc->sc_clks = sun8i_a83t_ccu_clks;
sc->sc_nclks = __arraycount(sun8i_a83t_ccu_clks);
if (sunxi_ccu_attach(sc) != 0)
return;
aprint_naive("\n");
aprint_normal(": A83T CCU\n");
sunxi_ccu_print(sc);
}

View File

@ -0,0 +1,34 @@
/* $NetBSD: sun8i_a83t_ccu.h,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#ifndef _SUN8I_A83T_CCU_H
#define _SUN8I_A83T_CCU_H
#include <arm/sunxi/sun8i_h3_ccu.h>
#endif /* !_SUN8I_A83T_CCU_H */

View File

@ -0,0 +1,181 @@
/* $NetBSD: sun8i_a83t_gpio.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2016-2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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 <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sun8i_a83t_gpio.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/types.h>
#include <arm/sunxi/sunxi_gpio.h>
static const struct sunxi_gpio_pins a83t_pins[] = {
{ "PB0", 1, 0, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
{ "PB1", 1, 1, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
{ "PB2", 1, 2, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
{ "PB3", 1, 3, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
{ "PB4", 1, 4, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
{ "PB5", 1, 5, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
{ "PB6", 1, 6, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
{ "PB7", 1, 7, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
{ "PB8", 1, 8, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
{ "PB9", 1, 9, { "gpio_in", "gpio_out", "uart0", NULL, NULL, NULL, "eint" } },
{ "PB10", 1, 10, { "gpio_in", "gpio_out", "uart0", NULL, NULL, NULL, "eint" } },
{ "PC0", 2, 0, { "gpio_in", "gpio_out", "nand", "spi0" } },
{ "PC1", 2, 1, { "gpio_in", "gpio_out", "nand", "spi0" } },
{ "PC2", 2, 2, { "gpio_in", "gpio_out", "nand", "spi0" } },
{ "PC3", 2, 3, { "gpio_in", "gpio_out", "nand", "spi0" } },
{ "PC4", 2, 4, { "gpio_in", "gpio_out", "nand" } },
{ "PC5", 2, 5, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC6", 2, 6, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC7", 2, 7, { "gpio_in", "gpio_out", "nand" } },
{ "PC8", 2, 8, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC9", 2, 9, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC10", 2, 10, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC11", 2, 11, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC12", 2, 12, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC13", 2, 13, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC14", 2, 14, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC15", 2, 15, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC16", 2, 16, { "gpio_in", "gpio_out", "nand", "mmc2" } },
{ "PC17", 2, 17, { "gpio_in", "gpio_out", "nand" } },
{ "PC18", 2, 18, { "gpio_in", "gpio_out", "nand" } },
{ "PD2", 3, 2, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD3", 3, 3, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD4", 3, 4, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD5", 3, 5, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD6", 3, 6, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD7", 3, 7, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD10", 3, 10, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD11", 3, 11, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD12", 3, 12, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD13", 3, 13, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD14", 3, 14, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD15", 3, 15, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
{ "PD18", 3, 18, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
{ "PD19", 3, 19, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
{ "PD20", 3, 20, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
{ "PD21", 3, 21, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
{ "PD22", 3, 22, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
{ "PD23", 3, 23, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
{ "PD24", 3, 24, { "gpio_in", "gpio_out", "lcd", "lvds" } },
{ "PD25", 3, 25, { "gpio_in", "gpio_out", "lcd", "lvds" } },
{ "PD26", 3, 26, { "gpio_in", "gpio_out", "lcd", "lvds" } },
{ "PD27", 3, 27, { "gpio_in", "gpio_out", "lcd", "lvds" } },
{ "PD28", 3, 28, { "gpio_in", "gpio_out", "pwm" } },
{ "PD29", 3, 29, { "gpio_in", "gpio_out" } },
{ "PE0", 4, 0, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
{ "PE1", 4, 1, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
{ "PE2", 4, 2, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
{ "PE3", 4, 3, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
{ "PE4", 4, 4, { "gpio_in", "gpio_out", "csi" } },
{ "PE5", 4, 5, { "gpio_in", "gpio_out", "csi" } },
{ "PE6", 4, 6, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
{ "PE7", 4, 7, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
{ "PE8", 4, 8, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
{ "PE9", 4, 9, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
{ "PE10", 4, 10, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
{ "PE11", 4, 11, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
{ "PE12", 4, 12, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
{ "PE13", 4, 13, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
{ "PE14", 4, 14, { "gpio_in", "gpio_out", "csi", "twi2" } },
{ "PE15", 4, 15, { "gpio_in", "gpio_out", "csi", "twi2" } },
{ "PE16", 4, 16, { "gpio_in", "gpio_out" } },
{ "PE17", 4, 17, { "gpio_in", "gpio_out" } },
{ "PE18", 4, 18, { "gpio_in", "gpio_out", NULL, "owa" } },
{ "PE19", 4, 19, { "gpio_in", "gpio_out" } },
{ "PF0", 5, 0, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
{ "PF1", 5, 1, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
{ "PF2", 5, 2, { "gpio_in", "gpio_out", "mmc0", "uart0" } },
{ "PF3", 5, 3, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
{ "PF4", 5, 4, { "gpio_in", "gpio_out", "mmc0", "uart0" } },
{ "PF5", 5, 5, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
{ "PF6", 5, 6, { "gpio_in", "gpio_out" } },
{ "PG0", 6, 0, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
{ "PG1", 6, 1, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
{ "PG2", 6, 2, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
{ "PG3", 6, 3, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
{ "PG4", 6, 4, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
{ "PG5", 6, 5, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
{ "PG6", 6, 6, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
{ "PG7", 6, 7, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
{ "PG8", 6, 8, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
{ "PG9", 6, 9, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
{ "PG10", 6, 10, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
{ "PG11", 6, 11, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
{ "PG12", 6, 12, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
{ "PG13", 6, 13, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
{ "PH0", 7, 0, { "gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, "eint" } },
{ "PH1", 7, 1, { "gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, "eint" } },
{ "PH2", 7, 2, { "gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, "eint" } },
{ "PH3", 7, 3, { "gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, "eint" } },
{ "PH4", 7, 4, { "gpio_in", "gpio_out", "i2c2", NULL, NULL, NULL, "eint" } },
{ "PH5", 7, 5, { "gpio_in", "gpio_out", "i2c2", NULL, NULL, NULL, "eint" } },
{ "PH6", 7, 6, { "gpio_in", "gpio_out", "hdmiddc", NULL, NULL, NULL, "eint" } },
{ "PH7", 7, 7, { "gpio_in", "gpio_out", "hdmiddc", NULL, NULL, NULL, "eint" } },
{ "PH8", 7, 8, { "gpio_in", "gpio_out", "hdmiddc", NULL, NULL, NULL, "eint" } },
{ "PH9", 7, 9, { "gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "eint" } },
{ "PH10", 7, 10, { "gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "eint" } },
{ "PH11", 7, 11, { "gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "eint" } },
};
static const struct sunxi_gpio_pins a83t_r_pins[] = {
{ "PL0", 0, 0, { "gpio_in", "gpio_out", "s_rsb", "s_i2c", NULL, NULL, "eint" } },
{ "PL1", 0, 1, { "gpio_in", "gpio_out", "s_rsb", "s_i2c", NULL, NULL, "eint" } },
{ "PL2", 0, 2, { "gpio_in", "gpio_out", "s_uart", NULL, NULL, NULL, "eint" } },
{ "PL3", 0, 3, { "gpio_in", "gpio_out", "s_uart", NULL, NULL, NULL, "eint" } },
{ "PL4", 0, 4, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
{ "PL5", 0, 5, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
{ "PL6", 0, 6, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
{ "PL7", 0, 7, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
{ "PL8", 0, 8, { "gpio_in", "gpio_out", "s_i2c", NULL, NULL, NULL, "eint" } },
{ "PL9", 0, 9, { "gpio_in", "gpio_out", "s_i2c", NULL, NULL, NULL, "eint" } },
{ "PL10", 0, 10, { "gpio_in", "gpio_out", "s_pwm", NULL, NULL, NULL, "eint" } },
{ "PL11", 0, 11, { "gpio_in", "gpio_out", NULL, NULL, NULL, "eint" } },
{ "PL12", 0, 12, { "gpio_in", "gpio_out", "s_cir", NULL, NULL, NULL, "eint" } },
};
const struct sunxi_gpio_padconf sun8i_a83t_padconf = {
.npins = __arraycount(a83t_pins),
.pins = a83t_pins,
};
const struct sunxi_gpio_padconf sun8i_a83t_r_padconf = {
.npins = __arraycount(a83t_r_pins),
.pins = a83t_r_pins,
};

View File

@ -0,0 +1,302 @@
/* $NetBSD: sun8i_h3_ccu.c,v 1.8.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* Copyright (c) 2017 Emmanuel Vadot <manu@freebsd.org>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: sun8i_h3_ccu.c,v 1.8.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <dev/fdt/fdtvar.h>
#include <arm/sunxi/sunxi_ccu.h>
#include <arm/sunxi/sun8i_h3_ccu.h>
#define PLL_PERIPH0_CTRL_REG 0x028
#define AHB1_APB1_CFG_REG 0x054
#define APB2_CFG_REG 0x058
#define AHB2_CFG_REG 0x05c
#define AHB2_CLK_CFG __BITS(1,0)
#define AHB2_CLK_CFG_PLL_PERIPH0_2 1
#define BUS_CLK_GATING_REG0 0x060
#define BUS_CLK_GATING_REG2 0x068
#define BUS_CLK_GATING_REG3 0x06c
#define SDMMC0_CLK_REG 0x088
#define SDMMC1_CLK_REG 0x08c
#define SDMMC2_CLK_REG 0x090
#define USBPHY_CFG_REG 0x0cc
#define MBUS_RST_REG 0x0fc
#define BUS_SOFT_RST_REG0 0x2c0
#define BUS_SOFT_RST_REG1 0x2c4
#define BUS_SOFT_RST_REG2 0x2c8
#define BUS_SOFT_RST_REG3 0x2d0
#define BUS_SOFT_RST_REG4 0x2d8
static int sun8i_h3_ccu_match(device_t, cfdata_t, void *);
static void sun8i_h3_ccu_attach(device_t, device_t, void *);
static const char * const compatible[] = {
"allwinner,sun8i-h3-ccu",
NULL
};
CFATTACH_DECL_NEW(sunxi_h3_ccu, sizeof(struct sunxi_ccu_softc),
sun8i_h3_ccu_match, sun8i_h3_ccu_attach, NULL, NULL);
static struct sunxi_ccu_reset sun8i_h3_ccu_resets[] = {
SUNXI_CCU_RESET(H3_RST_USB_PHY0, USBPHY_CFG_REG, 0),
SUNXI_CCU_RESET(H3_RST_USB_PHY1, USBPHY_CFG_REG, 1),
SUNXI_CCU_RESET(H3_RST_USB_PHY2, USBPHY_CFG_REG, 2),
SUNXI_CCU_RESET(H3_RST_USB_PHY3, USBPHY_CFG_REG, 3),
SUNXI_CCU_RESET(H3_RST_MBUS, MBUS_RST_REG, 31),
SUNXI_CCU_RESET(H3_RST_BUS_CE, BUS_SOFT_RST_REG0, 5),
SUNXI_CCU_RESET(H3_RST_BUS_DMA, BUS_SOFT_RST_REG0, 6),
SUNXI_CCU_RESET(H3_RST_BUS_MMC0, BUS_SOFT_RST_REG0, 8),
SUNXI_CCU_RESET(H3_RST_BUS_MMC1, BUS_SOFT_RST_REG0, 9),
SUNXI_CCU_RESET(H3_RST_BUS_MMC2, BUS_SOFT_RST_REG0, 10),
SUNXI_CCU_RESET(H3_RST_BUS_NAND, BUS_SOFT_RST_REG0, 13),
SUNXI_CCU_RESET(H3_RST_BUS_DRAM, BUS_SOFT_RST_REG0, 14),
SUNXI_CCU_RESET(H3_RST_BUS_EMAC, BUS_SOFT_RST_REG0, 17),
SUNXI_CCU_RESET(H3_RST_BUS_TS, BUS_SOFT_RST_REG0, 18),
SUNXI_CCU_RESET(H3_RST_BUS_HSTIMER, BUS_SOFT_RST_REG0, 19),
SUNXI_CCU_RESET(H3_RST_BUS_SPI0, BUS_SOFT_RST_REG0, 20),
SUNXI_CCU_RESET(H3_RST_BUS_SPI1, BUS_SOFT_RST_REG0, 21),
SUNXI_CCU_RESET(H3_RST_BUS_OTG, BUS_SOFT_RST_REG0, 23),
SUNXI_CCU_RESET(H3_RST_BUS_EHCI0, BUS_SOFT_RST_REG0, 24),
SUNXI_CCU_RESET(H3_RST_BUS_EHCI1, BUS_SOFT_RST_REG0, 25),
SUNXI_CCU_RESET(H3_RST_BUS_EHCI2, BUS_SOFT_RST_REG0, 26),
SUNXI_CCU_RESET(H3_RST_BUS_EHCI3, BUS_SOFT_RST_REG0, 27),
SUNXI_CCU_RESET(H3_RST_BUS_OHCI0, BUS_SOFT_RST_REG0, 28),
SUNXI_CCU_RESET(H3_RST_BUS_OHCI1, BUS_SOFT_RST_REG0, 29),
SUNXI_CCU_RESET(H3_RST_BUS_OHCI2, BUS_SOFT_RST_REG0, 30),
SUNXI_CCU_RESET(H3_RST_BUS_OHCI3, BUS_SOFT_RST_REG0, 31),
SUNXI_CCU_RESET(H3_RST_BUS_VE, BUS_SOFT_RST_REG1, 0),
SUNXI_CCU_RESET(H3_RST_BUS_TCON0, BUS_SOFT_RST_REG1, 3),
SUNXI_CCU_RESET(H3_RST_BUS_TCON1, BUS_SOFT_RST_REG1, 4),
SUNXI_CCU_RESET(H3_RST_BUS_DEINTERLACE, BUS_SOFT_RST_REG1, 5),
SUNXI_CCU_RESET(H3_RST_BUS_CSI, BUS_SOFT_RST_REG1, 8),
SUNXI_CCU_RESET(H3_RST_BUS_TVE, BUS_SOFT_RST_REG1, 9),
SUNXI_CCU_RESET(H3_RST_BUS_HDMI0, BUS_SOFT_RST_REG1, 10),
SUNXI_CCU_RESET(H3_RST_BUS_HDMI1, BUS_SOFT_RST_REG1, 11),
SUNXI_CCU_RESET(H3_RST_BUS_DE, BUS_SOFT_RST_REG1, 12),
SUNXI_CCU_RESET(H3_RST_BUS_GPU, BUS_SOFT_RST_REG1, 20),
SUNXI_CCU_RESET(H3_RST_BUS_MSGBOX, BUS_SOFT_RST_REG1, 21),
SUNXI_CCU_RESET(H3_RST_BUS_SPINLOCK, BUS_SOFT_RST_REG1, 22),
SUNXI_CCU_RESET(H3_RST_BUS_DBG, BUS_SOFT_RST_REG1, 31),
SUNXI_CCU_RESET(H3_RST_BUS_EPHY, BUS_SOFT_RST_REG2, 2),
SUNXI_CCU_RESET(H3_RST_BUS_CODEC, BUS_SOFT_RST_REG3, 0),
SUNXI_CCU_RESET(H3_RST_BUS_SPDIF, BUS_SOFT_RST_REG3, 1),
SUNXI_CCU_RESET(H3_RST_BUS_THS, BUS_SOFT_RST_REG3, 8),
SUNXI_CCU_RESET(H3_RST_BUS_I2S0, BUS_SOFT_RST_REG3, 12),
SUNXI_CCU_RESET(H3_RST_BUS_I2S1, BUS_SOFT_RST_REG3, 13),
SUNXI_CCU_RESET(H3_RST_BUS_I2S2, BUS_SOFT_RST_REG3, 14),
SUNXI_CCU_RESET(H3_RST_BUS_I2C0, BUS_SOFT_RST_REG4, 0),
SUNXI_CCU_RESET(H3_RST_BUS_I2C1, BUS_SOFT_RST_REG4, 1),
SUNXI_CCU_RESET(H3_RST_BUS_I2C2, BUS_SOFT_RST_REG4, 2),
SUNXI_CCU_RESET(H3_RST_BUS_UART0, BUS_SOFT_RST_REG4, 16),
SUNXI_CCU_RESET(H3_RST_BUS_UART1, BUS_SOFT_RST_REG4, 17),
SUNXI_CCU_RESET(H3_RST_BUS_UART2, BUS_SOFT_RST_REG4, 18),
SUNXI_CCU_RESET(H3_RST_BUS_UART3, BUS_SOFT_RST_REG4, 19),
SUNXI_CCU_RESET(H3_RST_BUS_SCR, BUS_SOFT_RST_REG4, 20),
};
static const char *ahb1_parents[] = { "losc", "hosc", "axi", "pll_periph0" };
static const char *ahb2_parents[] = { "ahb1", "pll_periph0" };
static const char *apb1_parents[] = { "ahb1" };
static const char *apb2_parents[] = { "losc", "hosc", "pll_periph0" };
static const char *mod_parents[] = { "hosc", "pll_periph0", "pll_periph1" };
static struct sunxi_ccu_clk sun8i_h3_ccu_clks[] = {
SUNXI_CCU_NKMP(H3_CLK_PLL_PERIPH0, "pll_periph0", "hosc",
PLL_PERIPH0_CTRL_REG, /* reg */
__BITS(12,8), /* n */
__BITS(5,4), /* k */
0, /* m */
__BITS(17,16), /* p */
__BIT(31), /* enable */
SUNXI_CCU_NKMP_DIVIDE_BY_TWO),
SUNXI_CCU_PREDIV(H3_CLK_AHB1, "ahb1", ahb1_parents,
AHB1_APB1_CFG_REG, /* reg */
__BITS(7,6), /* prediv */
__BIT(3), /* prediv_sel */
__BITS(5,4), /* div */
__BITS(13,12), /* sel */
SUNXI_CCU_PREDIV_POWER_OF_TWO),
SUNXI_CCU_PREDIV(H3_CLK_AHB2, "ahb2", ahb2_parents,
AHB2_CFG_REG, /* reg */
0, /* prediv */
__BIT(1), /* prediv_sel */
0, /* div */
__BITS(1,0), /* sel */
SUNXI_CCU_PREDIV_DIVIDE_BY_TWO),
SUNXI_CCU_DIV(H3_CLK_APB1, "apb1", apb1_parents,
AHB1_APB1_CFG_REG, /* reg */
__BITS(9,8), /* div */
0, /* sel */
SUNXI_CCU_DIV_POWER_OF_TWO|SUNXI_CCU_DIV_ZERO_IS_ONE),
SUNXI_CCU_NM(H3_CLK_APB2, "apb2", apb2_parents,
APB2_CFG_REG, /* reg */
__BITS(17,16), /* n */
__BITS(4,0), /* m */
__BITS(25,24), /* sel */
0, /* enable */
SUNXI_CCU_NM_POWER_OF_TWO),
SUNXI_CCU_NM(H3_CLK_MMC0, "mmc0", mod_parents,
SDMMC0_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
SUNXI_CCU_NM(H3_CLK_MMC1, "mmc1", mod_parents,
SDMMC1_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
SUNXI_CCU_NM(H3_CLK_MMC2, "mmc2", mod_parents,
SDMMC2_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
SUNXI_CCU_GATE(H3_CLK_BUS_MMC0, "bus-mmc0", "ahb1",
BUS_CLK_GATING_REG0, 8),
SUNXI_CCU_GATE(H3_CLK_BUS_MMC1, "bus-mmc1", "ahb1",
BUS_CLK_GATING_REG0, 9),
SUNXI_CCU_GATE(H3_CLK_BUS_MMC2, "bus-mmc2", "ahb1",
BUS_CLK_GATING_REG0, 10),
SUNXI_CCU_GATE(H3_CLK_BUS_EMAC, "bus-emac", "ahb2",
BUS_CLK_GATING_REG0, 17),
SUNXI_CCU_GATE(H3_CLK_BUS_OTG, "bus-otg", "ahb1",
BUS_CLK_GATING_REG0, 23),
SUNXI_CCU_GATE(H3_CLK_BUS_EHCI0, "bus-ehci0", "ahb1",
BUS_CLK_GATING_REG0, 24),
SUNXI_CCU_GATE(H3_CLK_BUS_EHCI1, "bus-ehci1", "ahb2",
BUS_CLK_GATING_REG0, 25),
SUNXI_CCU_GATE(H3_CLK_BUS_EHCI2, "bus-ehci2", "ahb2",
BUS_CLK_GATING_REG0, 26),
SUNXI_CCU_GATE(H3_CLK_BUS_EHCI3, "bus-ehci3", "ahb2",
BUS_CLK_GATING_REG0, 27),
SUNXI_CCU_GATE(H3_CLK_BUS_OHCI0, "bus-ohci0", "ahb1",
BUS_CLK_GATING_REG0, 28),
SUNXI_CCU_GATE(H3_CLK_BUS_OHCI1, "bus-ohci1", "ahb2",
BUS_CLK_GATING_REG0, 29),
SUNXI_CCU_GATE(H3_CLK_BUS_OHCI2, "bus-ohci2", "ahb2",
BUS_CLK_GATING_REG0, 30),
SUNXI_CCU_GATE(H3_CLK_BUS_OHCI3, "bus-ohci3", "ahb2",
BUS_CLK_GATING_REG0, 31),
SUNXI_CCU_GATE(H3_CLK_BUS_PIO, "bus-pio", "apb1",
BUS_CLK_GATING_REG2, 5),
SUNXI_CCU_GATE(H3_CLK_BUS_I2C0, "bus-i2c0", "apb2",
BUS_CLK_GATING_REG3, 0),
SUNXI_CCU_GATE(H3_CLK_BUS_I2C1, "bus-i2c1", "apb2",
BUS_CLK_GATING_REG3, 1),
SUNXI_CCU_GATE(H3_CLK_BUS_I2C2, "bus-i2c2", "apb2",
BUS_CLK_GATING_REG3, 2),
SUNXI_CCU_GATE(H3_CLK_BUS_UART0, "bus-uart0", "apb2",
BUS_CLK_GATING_REG3, 16),
SUNXI_CCU_GATE(H3_CLK_BUS_UART1, "bus-uart1", "apb2",
BUS_CLK_GATING_REG3, 17),
SUNXI_CCU_GATE(H3_CLK_BUS_UART2, "bus-uart2", "apb2",
BUS_CLK_GATING_REG3, 18),
SUNXI_CCU_GATE(H3_CLK_BUS_UART3, "bus-uart3", "apb2",
BUS_CLK_GATING_REG3, 19),
SUNXI_CCU_GATE(H3_CLK_USBPHY0, "usb-phy0", "hosc",
USBPHY_CFG_REG, 8),
SUNXI_CCU_GATE(H3_CLK_USBPHY1, "usb-phy1", "hosc",
USBPHY_CFG_REG, 9),
SUNXI_CCU_GATE(H3_CLK_USBPHY2, "usb-phy2", "hosc",
USBPHY_CFG_REG, 10),
SUNXI_CCU_GATE(H3_CLK_USBPHY3, "usb-phy3", "hosc",
USBPHY_CFG_REG, 11),
SUNXI_CCU_GATE(H3_CLK_USBOHCI0, "usb-ohci0", "hosc",
USBPHY_CFG_REG, 16),
SUNXI_CCU_GATE(H3_CLK_USBOHCI1, "usb-ohci1", "hosc",
USBPHY_CFG_REG, 17),
SUNXI_CCU_GATE(H3_CLK_USBOHCI2, "usb-ohci2", "hosc",
USBPHY_CFG_REG, 18),
SUNXI_CCU_GATE(H3_CLK_USBOHCI3, "usb-ohci3", "hosc",
USBPHY_CFG_REG, 19),
};
static void
sun8i_h3_ccu_init(struct sunxi_ccu_softc *sc)
{
uint32_t val;
/* Set AHB2 source to PLL_PERIPH/2 */
val = CCU_READ(sc, AHB2_CFG_REG);
val &= ~AHB2_CLK_CFG;
val |= __SHIFTIN(AHB2_CLK_CFG_PLL_PERIPH0_2, AHB2_CLK_CFG);
CCU_WRITE(sc, AHB2_CFG_REG, val);
}
static int
sun8i_h3_ccu_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
sun8i_h3_ccu_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_ccu_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
sc->sc_dev = self;
sc->sc_phandle = faa->faa_phandle;
sc->sc_bst = faa->faa_bst;
sc->sc_resets = sun8i_h3_ccu_resets;
sc->sc_nresets = __arraycount(sun8i_h3_ccu_resets);
sc->sc_clks = sun8i_h3_ccu_clks;
sc->sc_nclks = __arraycount(sun8i_h3_ccu_clks);
if (sunxi_ccu_attach(sc) != 0)
return;
aprint_naive("\n");
aprint_normal(": H3 CCU\n");
sun8i_h3_ccu_init(sc);
sunxi_ccu_print(sc);
}

View File

@ -0,0 +1,205 @@
/* $NetBSD: sun8i_h3_ccu.h,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Emmanuel Vadot <manu@freebsd.org>
* 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 ``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 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 __CCU_H3_H__
#define __CCU_H3_H__
#define H3_RST_USB_PHY0 0
#define H3_RST_USB_PHY1 1
#define H3_RST_USB_PHY2 2
#define H3_RST_USB_PHY3 3
#define H3_RST_MBUS 4
#define H3_RST_BUS_CE 5
#define H3_RST_BUS_DMA 6
#define H3_RST_BUS_MMC0 7
#define H3_RST_BUS_MMC1 8
#define H3_RST_BUS_MMC2 9
#define H3_RST_BUS_NAND 10
#define H3_RST_BUS_DRAM 11
#define H3_RST_BUS_EMAC 12
#define H3_RST_BUS_TS 13
#define H3_RST_BUS_HSTIMER 14
#define H3_RST_BUS_SPI0 15
#define H3_RST_BUS_SPI1 16
#define H3_RST_BUS_OTG 17
#define H3_RST_BUS_EHCI0 18
#define H3_RST_BUS_EHCI1 19
#define H3_RST_BUS_EHCI2 20
#define H3_RST_BUS_EHCI3 21
#define H3_RST_BUS_OHCI0 22
#define H3_RST_BUS_OHCI1 23
#define H3_RST_BUS_OHCI2 24
#define H3_RST_BUS_OHCI3 25
#define H3_RST_BUS_VE 26
#define H3_RST_BUS_TCON0 27
#define H3_RST_BUS_TCON1 28
#define H3_RST_BUS_DEINTERLACE 29
#define H3_RST_BUS_CSI 30
#define H3_RST_BUS_TVE 31
#define H3_RST_BUS_HDMI0 32
#define H3_RST_BUS_HDMI1 33
#define H3_RST_BUS_DE 34
#define H3_RST_BUS_GPU 35
#define H3_RST_BUS_MSGBOX 36
#define H3_RST_BUS_SPINLOCK 37
#define H3_RST_BUS_DBG 38
#define H3_RST_BUS_EPHY 39
#define H3_RST_BUS_CODEC 40
#define H3_RST_BUS_SPDIF 41
#define H3_RST_BUS_THS 42
#define H3_RST_BUS_I2S0 43
#define H3_RST_BUS_I2S1 44
#define H3_RST_BUS_I2S2 45
#define H3_RST_BUS_I2C0 46
#define H3_RST_BUS_I2C1 47
#define H3_RST_BUS_I2C2 48
#define H3_RST_BUS_UART0 49
#define H3_RST_BUS_UART1 50
#define H3_RST_BUS_UART2 51
#define H3_RST_BUS_UART3 52
#define H3_RST_BUS_SCR 53
#define H3_CLK_PLL_CPUX 0
#define H3_CLK_PLL_AUDIO_BASE 1
#define H3_CLK_PLL_AUDIO 2
#define H3_CLK_PLL_AUDIO_2X 3
#define H3_CLK_PLL_AUDIO_4X 4
#define H3_CLK_PLL_AUDIO_8X 5
#define H3_CLK_PLL_VIDEO 6
#define H3_CLK_PLL_VE 7
#define H3_CLK_PLL_DDR 8
#define H3_CLK_PLL_PERIPH0 9
#define H3_CLK_PLL_PERIPH0_2X 10
#define H3_CLK_PLL_GPU 11
#define H3_CLK_PLL_PERIPH1 12
#define H3_CLK_PLL_DE 13
#define H3_CLK_CPUX 14
#define H3_CLK_AXI 15
#define H3_CLK_AHB1 16
#define H3_CLK_APB1 17
#define H3_CLK_APB2 18
#define H3_CLK_AHB2 19
#define H3_CLK_BUS_CE 20
#define H3_CLK_BUS_DMA 21
#define H3_CLK_BUS_MMC0 22
#define H3_CLK_BUS_MMC1 23
#define H3_CLK_BUS_MMC2 24
#define H3_CLK_BUS_NAND 25
#define H3_CLK_BUS_DRAM 26
#define H3_CLK_BUS_EMAC 27
#define H3_CLK_BUS_TS 28
#define H3_CLK_BUS_HSTIMER 29
#define H3_CLK_BUS_SPI0 30
#define H3_CLK_BUS_SPI1 31
#define H3_CLK_BUS_OTG 32
#define H3_CLK_BUS_EHCI0 33
#define H3_CLK_BUS_EHCI1 34
#define H3_CLK_BUS_EHCI2 35
#define H3_CLK_BUS_EHCI3 36
#define H3_CLK_BUS_OHCI0 37
#define H3_CLK_BUS_OHCI1 38
#define H3_CLK_BUS_OHCI2 39
#define H3_CLK_BUS_OHCI3 40
#define H3_CLK_BUS_VE 41
#define H3_CLK_BUS_TCON0 42
#define H3_CLK_BUS_TCON1 43
#define H3_CLK_BUS_DEINTERLACE 44
#define H3_CLK_BUS_CSI 45
#define H3_CLK_BUS_TVE 46
#define H3_CLK_BUS_HDMI 47
#define H3_CLK_BUS_DE 48
#define H3_CLK_BUS_GPU 49
#define H3_CLK_BUS_MSGBOX 50
#define H3_CLK_BUS_SPINLOCK 51
#define H3_CLK_BUS_CODEC 52
#define H3_CLK_BUS_SPDIF 53
#define H3_CLK_BUS_PIO 54
#define H3_CLK_BUS_THS 55
#define H3_CLK_BUS_I2S0 56
#define H3_CLK_BUS_I2S1 57
#define H3_CLK_BUS_I2S2 58
#define H3_CLK_BUS_I2C0 59
#define H3_CLK_BUS_I2C1 60
#define H3_CLK_BUS_I2C2 61
#define H3_CLK_BUS_UART0 62
#define H3_CLK_BUS_UART1 63
#define H3_CLK_BUS_UART2 64
#define H3_CLK_BUS_UART3 65
#define H3_CLK_BUS_SCR 66
#define H3_CLK_BUS_EPHY 67
#define H3_CLK_BUS_DBG 68
#define H3_CLK_THS 69
#define H3_CLK_NAND 70
#define H3_CLK_MMC0 71
#define H3_CLK_MMC0_SAMPLE 72
#define H3_CLK_MMC0_OUTPUT 73
#define H3_CLK_MMC1 74
#define H3_CLK_MMC1_SAMPLE 75
#define H3_CLK_MMC1_OUTPUT 76
#define H3_CLK_MMC2 77
#define H3_CLK_MMC2_SAMPLE 78
#define H3_CLK_MMC2_OUTPUT 79
#define H3_CLK_TS 80
#define H3_CLK_CE 81
#define H3_CLK_SPI0 82
#define H3_CLK_SPI1 83
#define H3_CLK_I2S0 84
#define H3_CLK_I2S1 85
#define H3_CLK_I2S2 86
#define H3_CLK_SPDIF 87
#define H3_CLK_USBPHY0 88
#define H3_CLK_USBPHY1 89
#define H3_CLK_USBPHY2 90
#define H3_CLK_USBPHY3 91
#define H3_CLK_USBOHCI0 92
#define H3_CLK_USBOHCI1 93
#define H3_CLK_USBOHCI2 94
#define H3_CLK_USBOHCI3 95
#define H3_CLK_DRAM 96
#define H3_CLK_DRAM_VE 97
#define H3_CLK_DRAM_CSI 98
#define H3_CLK_DRAM_DEINTERLACE 99
#define H3_CLK_DRAM_TS 100
#define H3_CLK_DE 101
#define H3_CLK_TCON0 102
#define H3_CLK_TVE 103
#define H3_CLK_DEINTERLACE 104
#define H3_CLK_CSI_MISC 105
#define H3_CLK_CSI_SCLK 106
#define H3_CLK_CSI_MCLK 107
#define H3_CLK_VE 108
#define H3_CLK_AC_DIG 109
#define H3_CLK_AVS 110
#define H3_CLK_HDMI 111
#define H3_CLK_HDMI_DDC 112
#define H3_CLK_MBUS 113
#define H3_CLK_GPU 114
#endif /* __CCU_H3_H__ */

View File

@ -0,0 +1,165 @@
/* $NetBSD: sun8i_h3_gpio.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2016 Emmanuel Vadot <manu@freebsd.org>
* 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.
*
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sun8i_h3_gpio.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/types.h>
#include <arm/sunxi/sunxi_gpio.h>
static const struct sunxi_gpio_pins h3_pins[] = {
{"PA0", 0, 0, {"gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "pa_eint0", NULL}, 6, 0},
{"PA1", 0, 1, {"gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "pa_eint1", NULL}, 6, 1},
{"PA2", 0, 2, {"gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "pa_eint2", NULL}, 6, 2},
{"PA3", 0, 3, {"gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "pa_eint3", NULL}, 6, 3},
{"PA4", 0, 4, {"gpio_in", "gpio_out", "uart0", NULL, NULL, NULL, "pa_eint4", NULL}, 6, 4},
{"PA5", 0, 5, {"gpio_in", "gpio_out", "uart0", "pwm0", NULL, NULL, "pa_eint5", NULL}, 6, 5},
{"PA6", 0, 6, {"gpio_in", "gpio_out", "sim", NULL, NULL, NULL, "pa_eint6", NULL}, 6, 6},
{"PA7", 0, 7, {"gpio_in", "gpio_out", "sim", NULL, NULL, NULL, "pa_eint7", NULL}, 6, 7},
{"PA8", 0, 8, {"gpio_in", "gpio_out", "sim", NULL, NULL, NULL, "pa_eint8", NULL}, 6, 8},
{"PA9", 0, 9, {"gpio_in", "gpio_out", "sim", NULL, NULL, NULL, "pa_eint9", NULL}, 6, 9},
{"PA10", 0, 10, {"gpio_in", "gpio_out", "sim", NULL, NULL, NULL, "pa_eint10", NULL}, 6, 10},
{"PA11", 0, 11, {"gpio_in", "gpio_out", "i2c0", "di", NULL, NULL, "pa_eint11", NULL}, 6, 11},
{"PA12", 0, 12, {"gpio_in", "gpio_out", "i2c0", "di", NULL, NULL, "pa_eint12", NULL}, 6, 12},
{"PA13", 0, 13, {"gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "pa_eint13", NULL}, 6, 13},
{"PA14", 0, 14, {"gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "pa_eint14", NULL}, 6, 14},
{"PA15", 0, 15, {"gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "pa_eint15", NULL}, 6, 15},
{"PA16", 0, 16, {"gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "pa_eint16", NULL}, 6, 16},
{"PA17", 0, 17, {"gpio_in", "gpio_out", "spdif", NULL, NULL, NULL, "pa_eint17", NULL}, 6, 17},
{"PA18", 0, 18, {"gpio_in", "gpio_out", "i2s0", "i2c1", NULL, NULL, "pa_eint18", NULL}, 6, 18},
{"PA19", 0, 19, {"gpio_in", "gpio_out", "i2s0", "i2c1", NULL, NULL, "pa_eint19", NULL}, 6, 19},
{"PA20", 0, 20, {"gpio_in", "gpio_out", "i2s0", "sim", NULL, NULL, "pa_eint20", NULL}, 6, 20},
{"PA21", 0, 21, {"gpio_in", "gpio_out", "i2s0", "sim", NULL, NULL, "pa_eint21", NULL}, 6, 21},
{"PC0", 2, 0, {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
{"PC1", 2, 1, {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
{"PC2", 2, 2, {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
{"PC3", 2, 3, {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
{"PC4", 2, 4, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
{"PC5", 2, 5, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PC6", 2, 6, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PC7", 2, 7, {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
{"PC8", 2, 8, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PC9", 2, 9, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PC10", 2, 10, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PC11", 2, 11, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PC12", 2, 12, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PC13", 2, 13, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PC14", 2, 14, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PC15", 2, 15, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PC16", 2, 16, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
{"PD0", 3, 0, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD1", 3, 1, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD2", 3, 2, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD3", 3, 3, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD4", 3, 4, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD5", 3, 5, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD6", 3, 6, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD7", 3, 7, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD8", 3, 8, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD9", 3, 9, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD10", 3, 10, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD11", 3, 11, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD12", 3, 12, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD13", 3, 13, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD14", 3, 14, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD15", 3, 15, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD16", 3, 16, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PD17", 3, 17, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
{"PE0", 4, 0, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE1", 4, 1, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE2", 4, 2, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE3", 4, 3, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE4", 4, 4, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE5", 4, 5, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE6", 4, 6, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE7", 4, 7, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE8", 4, 8, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE9", 4, 9, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE10", 4, 10, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE11", 4, 11, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
{"PE12", 4, 12, {"gpio_in", "gpio_out", "csi", "i2c2", NULL, NULL, NULL, NULL}},
{"PE13", 4, 13, {"gpio_in", "gpio_out", "csi", "i2c2", NULL, NULL, NULL, NULL}},
{"PE14", 4, 14, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
{"PE15", 4, 15, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
{"PF0", 5, 0, {"gpio_in", "gpio_out", "mmc0", "jtag", NULL, NULL, NULL, NULL}},
{"PF1", 5, 1, {"gpio_in", "gpio_out", "mmc0", "jtag", NULL, NULL, NULL, NULL}},
{"PF2", 5, 2, {"gpio_in", "gpio_out", "mmc0", "uart0", NULL, NULL, NULL, NULL}},
{"PF3", 5, 3, {"gpio_in", "gpio_out", "mmc0", "jtag", NULL, NULL, NULL, NULL}},
{"PF4", 5, 4, {"gpio_in", "gpio_out", "mmc0", "uart0", NULL, NULL, NULL, NULL}},
{"PF5", 5, 5, {"gpio_in", "gpio_out", "mmc0", "jtag", NULL, NULL, NULL, NULL}},
{"PF6", 5, 6, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
{"PG0", 6, 0, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint0", NULL}, 6, 0},
{"PG1", 6, 1, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint1", NULL}, 6, 1},
{"PG2", 6, 2, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint2", NULL}, 6, 2},
{"PG3", 6, 3, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint3", NULL}, 6, 3},
{"PG4", 6, 4, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint4", NULL}, 6, 4},
{"PG5", 6, 5, {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint5", NULL}, 6, 5},
{"PG6", 6, 6, {"gpio_in", "gpio_out", "uart1", NULL, NULL, NULL, "pg_eint6", NULL}, 6, 6},
{"PG7", 6, 7, {"gpio_in", "gpio_out", "uart1", NULL, NULL, NULL, "pg_eint7", NULL}, 6, 7},
{"PG8", 6, 8, {"gpio_in", "gpio_out", "uart1", NULL, NULL, NULL, "pg_eint8", NULL}, 6, 8},
{"PG9", 6, 9, {"gpio_in", "gpio_out", "uart1", NULL, NULL, NULL, "pg_eint9", NULL}, 6, 9},
{"PG10", 6, 10, {"gpio_in", "gpio_out", "i2s1", NULL, NULL, NULL, "pg_eint10", NULL}, 6, 10},
{"PG11", 6, 11, {"gpio_in", "gpio_out", "i2s1", NULL, NULL, NULL, "pg_eint11", NULL}, 6, 11},
{"PG12", 6, 12, {"gpio_in", "gpio_out", "i2s1", NULL, NULL, NULL, "pg_eint12", NULL}, 6, 12},
{"PG13", 6, 13, {"gpio_in", "gpio_out", "i2s1", NULL, NULL, NULL, "pg_eint13", NULL}, 6, 13},
};
static const struct sunxi_gpio_pins h3_r_pins[] = {
{"PL0", 0, 0, {"gpio_in", "gpio_out", "s_twi", NULL, NULL, NULL, "pl_eint0", NULL}, 6, 0},
{"PL1", 0, 1, {"gpio_in", "gpio_out", "s_twi", NULL, NULL, NULL, "pl_eint1", NULL}, 6, 1},
{"PL2", 0, 2, {"gpio_in", "gpio_out", "s_uart", NULL, NULL, NULL, "pl_eint2", NULL}, 6, 2},
{"PL3", 0, 3, {"gpio_in", "gpio_out", "s_uart", NULL, NULL, NULL, "pl_eint3", NULL}, 6, 3},
{"PL4", 0, 4, {"gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "pl_eint4", NULL}, 6, 4},
{"PL5", 0, 5, {"gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "pl_eint5", NULL}, 6, 5},
{"PL6", 0, 6, {"gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "pl_eint6", NULL}, 6, 6},
{"PL7", 0, 7, {"gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "pl_eint7", NULL}, 6, 7},
{"PL8", 0, 8, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "pl_eint8", NULL}, 6, 8},
{"PL9", 0, 9, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "pl_eint9", NULL}, 6, 9},
{"PL10", 0, 10, {"gpio_in", "gpio_out", "s_pwm", NULL, NULL, NULL, "pl_eint10", NULL}, 6, 10},
{"PL11", 0, 11, {"gpio_in", "gpio_out", "s_cir_rx", NULL, NULL, NULL, "pl_eint11", NULL}, 6, 11},
};
const struct sunxi_gpio_padconf sun8i_h3_padconf = {
.npins = __arraycount(h3_pins),
.pins = h3_pins,
};
const struct sunxi_gpio_padconf sun8i_h3_r_padconf = {
.npins = __arraycount(h3_r_pins),
.pins = h3_r_pins,
};

View File

@ -0,0 +1,344 @@
/* $NetBSD: sunxi_ccu.c,v 1.6.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include "opt_soc.h"
#include "opt_multiprocessor.h"
#include "opt_fdt_arm.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu.c,v 1.6.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <dev/fdt/fdtvar.h>
#include <dev/clk/clk_backend.h>
#include <arm/sunxi/sunxi_ccu.h>
static void *
sunxi_ccu_reset_acquire(device_t dev, const void *data, size_t len)
{
struct sunxi_ccu_softc * const sc = device_private(dev);
struct sunxi_ccu_reset *reset;
if (len != 4)
return NULL;
const u_int reset_id = be32dec(data);
if (reset_id >= sc->sc_nresets)
return NULL;
reset = &sc->sc_resets[reset_id];
if (reset->mask == 0)
return NULL;
return reset;
}
static void
sunxi_ccu_reset_release(device_t dev, void *priv)
{
}
static int
sunxi_ccu_reset_assert(device_t dev, void *priv)
{
struct sunxi_ccu_softc * const sc = device_private(dev);
struct sunxi_ccu_reset * const reset = priv;
const uint32_t val = CCU_READ(sc, reset->reg);
CCU_WRITE(sc, reset->reg, val & ~reset->mask);
return 0;
}
static int
sunxi_ccu_reset_deassert(device_t dev, void *priv)
{
struct sunxi_ccu_softc * const sc = device_private(dev);
struct sunxi_ccu_reset * const reset = priv;
const uint32_t val = CCU_READ(sc, reset->reg);
CCU_WRITE(sc, reset->reg, val | reset->mask);
return 0;
}
static const struct fdtbus_reset_controller_func sunxi_ccu_fdtreset_funcs = {
.acquire = sunxi_ccu_reset_acquire,
.release = sunxi_ccu_reset_release,
.reset_assert = sunxi_ccu_reset_assert,
.reset_deassert = sunxi_ccu_reset_deassert,
};
static struct clk *
sunxi_ccu_clock_decode(device_t dev, const void *data, size_t len)
{
struct sunxi_ccu_softc * const sc = device_private(dev);
struct sunxi_ccu_clk *clk;
if (len != 4)
return NULL;
const u_int clock_id = be32dec(data);
if (clock_id >= sc->sc_nclks)
return NULL;
clk = &sc->sc_clks[clock_id];
if (clk->type == SUNXI_CCU_UNKNOWN)
return NULL;
return &clk->base;
}
static const struct fdtbus_clock_controller_func sunxi_ccu_fdtclock_funcs = {
.decode = sunxi_ccu_clock_decode,
};
static struct clk *
sunxi_ccu_clock_get(void *priv, const char *name)
{
struct sunxi_ccu_softc * const sc = priv;
struct sunxi_ccu_clk *clk;
clk = sunxi_ccu_clock_find(sc, name);
if (clk == NULL)
return NULL;
return &clk->base;
}
static void
sunxi_ccu_clock_put(void *priv, struct clk *clk)
{
}
static u_int
sunxi_ccu_clock_get_rate(void *priv, struct clk *clkp)
{
struct sunxi_ccu_softc * const sc = priv;
struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
struct clk *clkp_parent;
if (clk->get_rate)
return clk->get_rate(sc, clk);
clkp_parent = clk_get_parent(clkp);
if (clkp_parent == NULL) {
aprint_error("%s: no parent for %s\n", __func__, clk->base.name);
return 0;
}
return clk_get_rate(clkp_parent);
}
static int
sunxi_ccu_clock_set_rate(void *priv, struct clk *clkp, u_int rate)
{
struct sunxi_ccu_softc * const sc = priv;
struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
struct clk *clkp_parent;
if (clkp->flags & CLK_SET_RATE_PARENT) {
clkp_parent = clk_get_parent(clkp);
if (clkp_parent == NULL) {
aprint_error("%s: no parent for %s\n", __func__, clk->base.name);
return ENXIO;
}
return clk_set_rate(clkp_parent, rate);
}
if (clk->set_rate)
return clk->set_rate(sc, clk, rate);
return ENXIO;
}
static int
sunxi_ccu_clock_enable(void *priv, struct clk *clkp)
{
struct sunxi_ccu_softc * const sc = priv;
struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
struct clk *clkp_parent;
int error = 0;
clkp_parent = clk_get_parent(clkp);
if (clkp_parent != NULL) {
error = clk_enable(clkp_parent);
if (error != 0)
return error;
}
if (clk->enable)
error = clk->enable(sc, clk, 1);
return error;
}
static int
sunxi_ccu_clock_disable(void *priv, struct clk *clkp)
{
struct sunxi_ccu_softc * const sc = priv;
struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
int error = EINVAL;
if (clk->enable)
error = clk->enable(sc, clk, 0);
return error;
}
static int
sunxi_ccu_clock_set_parent(void *priv, struct clk *clkp,
struct clk *clkp_parent)
{
struct sunxi_ccu_softc * const sc = priv;
struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
if (clk->set_parent == NULL)
return EINVAL;
return clk->set_parent(sc, clk, clkp_parent->name);
}
static struct clk *
sunxi_ccu_clock_get_parent(void *priv, struct clk *clkp)
{
struct sunxi_ccu_softc * const sc = priv;
struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
struct sunxi_ccu_clk *clk_parent;
const char *parent;
if (clk->get_parent == NULL)
return NULL;
parent = clk->get_parent(sc, clk);
if (parent == NULL)
return NULL;
clk_parent = sunxi_ccu_clock_find(sc, parent);
if (clk_parent != NULL)
return &clk_parent->base;
/* No parent in this domain, try FDT */
return fdtbus_clock_get(sc->sc_phandle, parent);
}
static const struct clk_funcs sunxi_ccu_clock_funcs = {
.get = sunxi_ccu_clock_get,
.put = sunxi_ccu_clock_put,
.get_rate = sunxi_ccu_clock_get_rate,
.set_rate = sunxi_ccu_clock_set_rate,
.enable = sunxi_ccu_clock_enable,
.disable = sunxi_ccu_clock_disable,
.set_parent = sunxi_ccu_clock_set_parent,
.get_parent = sunxi_ccu_clock_get_parent,
};
struct sunxi_ccu_clk *
sunxi_ccu_clock_find(struct sunxi_ccu_softc *sc, const char *name)
{
for (int i = 0; i < sc->sc_nclks; i++) {
if (sc->sc_clks[i].base.name == NULL)
continue;
if (strcmp(sc->sc_clks[i].base.name, name) == 0)
return &sc->sc_clks[i];
}
return NULL;
}
int
sunxi_ccu_attach(struct sunxi_ccu_softc *sc)
{
bus_addr_t addr;
bus_size_t size;
int i;
if (fdtbus_get_reg(sc->sc_phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return ENXIO;
}
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
aprint_error(": couldn't map registers\n");
return ENXIO;
}
sc->sc_clkdom.funcs = &sunxi_ccu_clock_funcs;
sc->sc_clkdom.priv = sc;
for (i = 0; i < sc->sc_nclks; i++)
sc->sc_clks[i].base.domain = &sc->sc_clkdom;
fdtbus_register_clock_controller(sc->sc_dev, sc->sc_phandle,
&sunxi_ccu_fdtclock_funcs);
fdtbus_register_reset_controller(sc->sc_dev, sc->sc_phandle,
&sunxi_ccu_fdtreset_funcs);
return 0;
}
void
sunxi_ccu_print(struct sunxi_ccu_softc *sc)
{
struct sunxi_ccu_clk *clk;
struct clk *clkp_parent;
const char *type;
int i;
for (i = 0; i < sc->sc_nclks; i++) {
clk = &sc->sc_clks[i];
if (clk->type == SUNXI_CCU_UNKNOWN)
continue;
clkp_parent = clk_get_parent(&clk->base);
switch (clk->type) {
case SUNXI_CCU_GATE: type = "gate"; break;
case SUNXI_CCU_NM: type = "nm"; break;
case SUNXI_CCU_NKMP: type = "nkmp"; break;
case SUNXI_CCU_PREDIV: type = "prediv"; break;
case SUNXI_CCU_DIV: type = "div"; break;
default: type = "???"; break;
}
aprint_debug_dev(sc->sc_dev,
"%3d %-12s %2s %-12s %-7s ",
i,
clk->base.name,
clkp_parent ? "<-" : "",
clkp_parent ? clkp_parent->name : "",
type);
aprint_debug("%10d Hz\n", clk_get_rate(&clk->base));
}
}

View File

@ -0,0 +1,304 @@
/* $NetBSD: sunxi_ccu.h,v 1.7.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#ifndef _ARM_SUNXI_CCU_H
#define _ARM_SUNXI_CCU_H
#include <dev/clk/clk_backend.h>
struct sunxi_ccu_softc;
struct sunxi_ccu_clk;
struct sunxi_ccu_reset;
/*
* Resets
*/
struct sunxi_ccu_reset {
bus_size_t reg;
uint32_t mask;
};
#define SUNXI_CCU_RESET(_id, _reg, _bit) \
[_id] = { \
.reg = (_reg), \
.mask = __BIT(_bit), \
}
/*
* Clocks
*/
enum sunxi_ccu_clktype {
SUNXI_CCU_UNKNOWN,
SUNXI_CCU_GATE,
SUNXI_CCU_NM,
SUNXI_CCU_NKMP,
SUNXI_CCU_PREDIV,
SUNXI_CCU_DIV,
};
struct sunxi_ccu_gate {
bus_size_t reg;
uint32_t mask;
const char *parent;
};
int sunxi_ccu_gate_enable(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *, int);
const char *sunxi_ccu_gate_get_parent(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
#define SUNXI_CCU_GATE(_id, _name, _pname, _reg, _bit) \
[_id] = { \
.type = SUNXI_CCU_GATE, \
.base.name = (_name), \
.u.gate.parent = (_pname), \
.u.gate.reg = (_reg), \
.u.gate.mask = __BIT(_bit), \
.enable = sunxi_ccu_gate_enable, \
.get_parent = sunxi_ccu_gate_get_parent, \
}
struct sunxi_ccu_nkmp {
bus_size_t reg;
const char *parent;
uint32_t n;
uint32_t k;
uint32_t m;
uint32_t p;
uint32_t lock;
uint32_t enable;
uint32_t flags;
#define SUNXI_CCU_NKMP_DIVIDE_BY_TWO __BIT(0)
#define SUNXI_CCU_NKMP_FACTOR_N_EXACT __BIT(1)
};
int sunxi_ccu_nkmp_enable(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *, int);
u_int sunxi_ccu_nkmp_get_rate(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
int sunxi_ccu_nkmp_set_rate(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *, u_int);
const char *sunxi_ccu_nkmp_get_parent(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
#define SUNXI_CCU_NKMP(_id, _name, _parent, _reg, _n, _k, _m, \
_p, _enable, _flags) \
[_id] = { \
.type = SUNXI_CCU_NKMP, \
.base.name = (_name), \
.u.nkmp.reg = (_reg), \
.u.nkmp.parent = (_parent), \
.u.nkmp.n = (_n), \
.u.nkmp.k = (_k), \
.u.nkmp.m = (_m), \
.u.nkmp.p = (_p), \
.u.nkmp.enable = (_enable), \
.u.nkmp.flags = (_flags), \
.enable = sunxi_ccu_nkmp_enable, \
.get_rate = sunxi_ccu_nkmp_get_rate, \
.set_rate = sunxi_ccu_nkmp_set_rate, \
.get_parent = sunxi_ccu_nkmp_get_parent, \
}
struct sunxi_ccu_nm {
bus_size_t reg;
const char **parents;
u_int nparents;
uint32_t n;
uint32_t m;
uint32_t sel;
uint32_t enable;
uint32_t flags;
#define SUNXI_CCU_NM_POWER_OF_TWO __BIT(0)
#define SUNXI_CCU_NM_ROUND_DOWN __BIT(1)
};
int sunxi_ccu_nm_enable(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *, int);
u_int sunxi_ccu_nm_get_rate(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
int sunxi_ccu_nm_set_rate(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *, u_int);
int sunxi_ccu_nm_set_parent(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *,
const char *);
const char *sunxi_ccu_nm_get_parent(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
#define SUNXI_CCU_NM(_id, _name, _parents, _reg, _n, _m, _sel, \
_enable, _flags) \
[_id] = { \
.type = SUNXI_CCU_NM, \
.base.name = (_name), \
.u.nm.reg = (_reg), \
.u.nm.parents = (_parents), \
.u.nm.nparents = __arraycount(_parents), \
.u.nm.n = (_n), \
.u.nm.m = (_m), \
.u.nm.sel = (_sel), \
.u.nm.enable = (_enable), \
.u.nm.flags = (_flags), \
.enable = sunxi_ccu_nm_enable, \
.get_rate = sunxi_ccu_nm_get_rate, \
.set_rate = sunxi_ccu_nm_set_rate, \
.set_parent = sunxi_ccu_nm_set_parent, \
.get_parent = sunxi_ccu_nm_get_parent, \
}
struct sunxi_ccu_div {
bus_size_t reg;
const char **parents;
u_int nparents;
uint32_t div;
uint32_t sel;
uint32_t flags;
#define SUNXI_CCU_DIV_POWER_OF_TWO __BIT(0)
#define SUNXI_CCU_DIV_ZERO_IS_ONE __BIT(1)
};
u_int sunxi_ccu_div_get_rate(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
int sunxi_ccu_div_set_rate(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *, u_int);
int sunxi_ccu_div_set_parent(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *,
const char *);
const char *sunxi_ccu_div_get_parent(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
#define SUNXI_CCU_DIV(_id, _name, _parents, _reg, _div, \
_sel, _flags) \
[_id] = { \
.type = SUNXI_CCU_DIV, \
.base.name = (_name), \
.u.div.reg = (_reg), \
.u.div.parents = (_parents), \
.u.div.nparents = __arraycount(_parents), \
.u.div.div = (_div), \
.u.div.sel = (_sel), \
.u.div.flags = (_flags), \
.get_rate = sunxi_ccu_div_get_rate, \
.set_rate = sunxi_ccu_div_set_rate, \
.set_parent = sunxi_ccu_div_set_parent, \
.get_parent = sunxi_ccu_div_get_parent, \
}
struct sunxi_ccu_prediv {
bus_size_t reg;
const char **parents;
u_int nparents;
uint32_t prediv;
uint32_t prediv_sel;
uint32_t div;
uint32_t sel;
uint32_t flags;
#define SUNXI_CCU_PREDIV_POWER_OF_TWO __BIT(0)
#define SUNXI_CCU_PREDIV_DIVIDE_BY_TWO __BIT(1)
};
u_int sunxi_ccu_prediv_get_rate(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
int sunxi_ccu_prediv_set_rate(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *, u_int);
int sunxi_ccu_prediv_set_parent(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *,
const char *);
const char *sunxi_ccu_prediv_get_parent(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
#define SUNXI_CCU_PREDIV(_id, _name, _parents, _reg, _prediv, \
_prediv_sel, _div, _sel, _flags) \
[_id] = { \
.type = SUNXI_CCU_PREDIV, \
.base.name = (_name), \
.u.prediv.reg = (_reg), \
.u.prediv.parents = (_parents), \
.u.prediv.nparents = __arraycount(_parents), \
.u.prediv.prediv = (_prediv), \
.u.prediv.prediv_sel = (_prediv_sel), \
.u.prediv.div = (_div), \
.u.prediv.sel = (_sel), \
.u.prediv.flags = (_flags), \
.get_rate = sunxi_ccu_prediv_get_rate, \
.set_rate = sunxi_ccu_prediv_set_rate, \
.set_parent = sunxi_ccu_prediv_set_parent, \
.get_parent = sunxi_ccu_prediv_get_parent, \
}
struct sunxi_ccu_clk {
struct clk base;
enum sunxi_ccu_clktype type;
union {
struct sunxi_ccu_gate gate;
struct sunxi_ccu_nm nm;
struct sunxi_ccu_nkmp nkmp;
struct sunxi_ccu_prediv prediv;
struct sunxi_ccu_div div;
} u;
int (*enable)(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *, int);
u_int (*get_rate)(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
int (*set_rate)(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *, u_int);
const char * (*get_parent)(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *);
int (*set_parent)(struct sunxi_ccu_softc *,
struct sunxi_ccu_clk *,
const char *);
};
struct sunxi_ccu_softc {
device_t sc_dev;
int sc_phandle;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
struct clk_domain sc_clkdom;
struct sunxi_ccu_reset *sc_resets;
u_int sc_nresets;
struct sunxi_ccu_clk *sc_clks;
u_int sc_nclks;
};
int sunxi_ccu_attach(struct sunxi_ccu_softc *);
struct sunxi_ccu_clk *sunxi_ccu_clock_find(struct sunxi_ccu_softc *,
const char *);
void sunxi_ccu_print(struct sunxi_ccu_softc *);
#define CCU_READ(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define CCU_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
#endif /* _ARM_SUNXI_CCU_H */

View File

@ -0,0 +1,124 @@
/* $NetBSD: sunxi_ccu_div.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_div.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <dev/clk/clk_backend.h>
#include <arm/sunxi/sunxi_ccu.h>
u_int
sunxi_ccu_div_get_rate(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk)
{
struct sunxi_ccu_div *div = &clk->u.div;
struct clk *clkp, *clkp_parent;
u_int rate, ratio;
uint32_t val;
KASSERT(clk->type == SUNXI_CCU_DIV);
clkp = &clk->base;
clkp_parent = clk_get_parent(clkp);
if (clkp_parent == NULL)
return 0;
rate = clk_get_rate(clkp_parent);
if (rate == 0)
return 0;
val = CCU_READ(sc, div->reg);
ratio = __SHIFTOUT(val, div->div);
if ((div->flags & SUNXI_CCU_DIV_ZERO_IS_ONE) != 0 && ratio == 0)
ratio = 1;
if (div->flags & SUNXI_CCU_DIV_POWER_OF_TWO)
ratio = 1 << ratio;
else
ratio++;
return rate / ratio;
}
int
sunxi_ccu_div_set_rate(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk, u_int new_rate)
{
return EINVAL;
}
int
sunxi_ccu_div_set_parent(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk, const char *name)
{
struct sunxi_ccu_div *div = &clk->u.div;
uint32_t val;
u_int index;
KASSERT(clk->type == SUNXI_CCU_DIV);
if (div->sel == 0)
return ENODEV;
for (index = 0; index < div->nparents; index++) {
if (div->parents[index] != NULL &&
strcmp(div->parents[index], name) == 0)
break;
}
if (index == div->nparents)
return EINVAL;
val = CCU_READ(sc, div->reg);
val &= ~div->sel;
val |= __SHIFTIN(index, div->sel);
CCU_WRITE(sc, div->reg, val);
return 0;
}
const char *
sunxi_ccu_div_get_parent(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk)
{
struct sunxi_ccu_div *div = &clk->u.div;
u_int index;
uint32_t val;
KASSERT(clk->type == SUNXI_CCU_DIV);
if (div->sel == 0)
return div->parents[0];
val = CCU_READ(sc, div->reg);
index = __SHIFTOUT(val, div->sel);
return div->parents[index];
}

View File

@ -1,7 +1,7 @@
/* $NetBSD: exynos_fdt.c,v 1.4 2017/04/16 15:52:16 jmcneill Exp $ */
/* $NetBSD: sunxi_ccu_gate.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,55 +26,41 @@
* SUCH DAMAGE.
*/
#include "opt_exynos.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exynos_fdt.c,v 1.4 2017/04/16 15:52:16 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_gate.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <machine/cpu.h>
#include <sys/bus.h>
#include <arm/mainbus/mainbus.h>
#include <arm/samsung/exynos_reg.h>
#include <arm/samsung/exynos_var.h>
#include <dev/clk/clk_backend.h>
#include <dev/fdt/fdtvar.h>
#include <dev/ofw/openfirm.h>
static int exynosfdt_match(device_t, cfdata_t, void *);
static void exynosfdt_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(exynos_fdt, 0,
exynosfdt_match, exynosfdt_attach, NULL, NULL);
static bool exynosfdt_found = false;
#include <arm/sunxi/sunxi_ccu.h>
int
exynosfdt_match(device_t parent, cfdata_t cf, void *aux)
sunxi_ccu_gate_enable(struct sunxi_ccu_softc *sc, struct sunxi_ccu_clk *clk,
int enable)
{
if (exynosfdt_found)
return 0;
return 1;
struct sunxi_ccu_gate *gate = &clk->u.gate;
uint32_t val;
KASSERT(clk->type == SUNXI_CCU_GATE);
val = CCU_READ(sc, gate->reg);
if (enable)
val |= gate->mask;
else
val &= ~gate->mask;
CCU_WRITE(sc, gate->reg, val);
return 0;
}
void
exynosfdt_attach(device_t parent, device_t self, void *aux)
const char *
sunxi_ccu_gate_get_parent(struct sunxi_ccu_softc *sc, struct sunxi_ccu_clk *clk)
{
exynosfdt_found = true;
struct sunxi_ccu_gate *gate = &clk->u.gate;
aprint_naive("\n");
aprint_normal("\n");
KASSERT(clk->type == SUNXI_CCU_GATE);
struct fdt_attach_args faa = {
.faa_name = "",
.faa_bst = &armv7_generic_bs_tag,
.faa_a4x_bst = &armv7_generic_a4x_bs_tag,
.faa_dmat = &exynos_bus_dma_tag,
.faa_phandle = OF_peer(0),
};
config_found(self, &faa, NULL);
return gate->parent;
}

View File

@ -0,0 +1,130 @@
/* $NetBSD: sunxi_ccu_nkmp.c,v 1.4.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_nkmp.c,v 1.4.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <dev/clk/clk_backend.h>
#include <arm/sunxi/sunxi_ccu.h>
int
sunxi_ccu_nkmp_enable(struct sunxi_ccu_softc *sc, struct sunxi_ccu_clk *clk,
int enable)
{
struct sunxi_ccu_nkmp *nkmp = &clk->u.nkmp;
uint32_t val;
KASSERT(clk->type == SUNXI_CCU_NKMP);
if (!nkmp->enable)
return enable ? 0 : EINVAL;
val = CCU_READ(sc, nkmp->reg);
if (enable)
val |= nkmp->enable;
else
val &= ~nkmp->enable;
CCU_WRITE(sc, nkmp->reg, val);
return 0;
}
u_int
sunxi_ccu_nkmp_get_rate(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk)
{
struct sunxi_ccu_nkmp *nkmp = &clk->u.nkmp;
struct clk *clkp, *clkp_parent;
u_int rate, n, k, m, p;
uint32_t val;
KASSERT(clk->type == SUNXI_CCU_NKMP);
clkp = &clk->base;
clkp_parent = clk_get_parent(clkp);
if (clkp_parent == NULL)
return 0;
rate = clk_get_rate(clkp_parent);
if (rate == 0)
return 0;
val = CCU_READ(sc, nkmp->reg);
if (nkmp->n)
n = __SHIFTOUT(val, nkmp->n);
else
n = 0;
if (nkmp->k)
k = __SHIFTOUT(val, nkmp->k);
else
k = 0;
if (nkmp->m)
m = __SHIFTOUT(val, nkmp->m);
else
m = 0;
if (nkmp->p)
p = __SHIFTOUT(val, nkmp->p);
else
p = 0;
if (nkmp->enable && !(val & nkmp->enable))
return 0;
if ((nkmp->flags & SUNXI_CCU_NKMP_FACTOR_N_EXACT) == 0)
n++;
k++;
m++;
p++;
if (nkmp->flags & SUNXI_CCU_NKMP_DIVIDE_BY_TWO)
m *= 2;
return (u_int)((uint64_t)rate * n * k) / (m * p);
}
int
sunxi_ccu_nkmp_set_rate(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk, u_int rate)
{
return EIO;
}
const char *
sunxi_ccu_nkmp_get_parent(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk)
{
struct sunxi_ccu_nkmp *nkmp = &clk->u.nkmp;
KASSERT(clk->type == SUNXI_CCU_NKMP);
return nkmp->parent;
}

View File

@ -0,0 +1,227 @@
/* $NetBSD: sunxi_ccu_nm.c,v 1.3.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_nm.c,v 1.3.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <dev/clk/clk_backend.h>
#include <arm/sunxi/sunxi_ccu.h>
int
sunxi_ccu_nm_enable(struct sunxi_ccu_softc *sc, struct sunxi_ccu_clk *clk,
int enable)
{
struct sunxi_ccu_nm *nm = &clk->u.nm;
uint32_t val;
KASSERT(clk->type == SUNXI_CCU_NM);
if (!nm->enable)
return enable ? 0 : EINVAL;
val = CCU_READ(sc, nm->reg);
if (enable)
val |= nm->enable;
else
val &= ~nm->enable;
CCU_WRITE(sc, nm->reg, val);
return 0;
}
u_int
sunxi_ccu_nm_get_rate(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk)
{
struct sunxi_ccu_nm *nm = &clk->u.nm;
struct clk *clkp, *clkp_parent;
u_int rate, n, m;
uint32_t val;
KASSERT(clk->type == SUNXI_CCU_NM);
clkp = &clk->base;
clkp_parent = clk_get_parent(clkp);
if (clkp_parent == NULL)
return 0;
rate = clk_get_rate(clkp_parent);
if (rate == 0)
return 0;
val = CCU_READ(sc, nm->reg);
n = __SHIFTOUT(val, nm->n);
m = __SHIFTOUT(val, nm->m);
if (nm->enable && !(val & nm->enable))
return 0;
if (nm->flags & SUNXI_CCU_NM_POWER_OF_TWO)
n = 1 << n;
else
n++;
m++;
return rate / n / m;
}
int
sunxi_ccu_nm_set_rate(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk, u_int new_rate)
{
struct sunxi_ccu_nm *nm = &clk->u.nm;
struct clk *clkp, *clkp_parent;
u_int parent_rate, best_rate, best_n, best_m, best_parent;
u_int n, m, pindex, rate;
int best_diff;
uint32_t val;
const u_int n_max = __SHIFTOUT(nm->n, nm->n);
const u_int m_max = __SHIFTOUT(nm->m, nm->m);
clkp = &clk->base;
clkp_parent = clk_get_parent(clkp);
if (clkp_parent == NULL)
return 0;
rate = clk_get_rate(clkp_parent);
if (rate == 0)
return 0;
best_rate = 0;
best_diff = INT_MAX;
for (pindex = 0; pindex < nm->nparents; pindex++) {
/* XXX
* Shouldn't have to set parent to get potential parent clock rate
*/
val = CCU_READ(sc, nm->reg);
val &= ~nm->sel;
val |= __SHIFTIN(pindex, nm->sel);
CCU_WRITE(sc, nm->reg, val);
clkp_parent = clk_get_parent(clkp);
if (clkp_parent == NULL)
continue;
parent_rate = clk_get_rate(clkp_parent);
if (parent_rate == 0)
continue;
for (n = 0; n <= n_max; n++) {
for (m = 0; m <= m_max; m++) {
if (nm->flags & SUNXI_CCU_NM_POWER_OF_TWO)
rate = parent_rate / (1 << n) / (m + 1);
else
rate = parent_rate / (n + 1) / (m + 1);
if (nm->flags & SUNXI_CCU_NM_ROUND_DOWN) {
const int diff = new_rate - rate;
if (diff >= 0 && rate > best_rate) {
best_diff = diff;
best_rate = rate;
best_n = n;
best_m = m;
best_parent = pindex;
}
} else {
const int diff = abs(new_rate - rate);
if (diff < best_diff) {
best_diff = diff;
best_rate = rate;
best_n = n;
best_m = m;
best_parent = pindex;
}
}
}
}
}
if (best_rate == 0)
return ERANGE;
val = CCU_READ(sc, nm->reg);
val &= ~nm->sel;
val |= __SHIFTIN(best_parent, nm->sel);
val &= ~nm->n;
val |= __SHIFTIN(best_n, nm->n);
val &= ~nm->m;
val |= __SHIFTIN(best_m, nm->m);
CCU_WRITE(sc, nm->reg, val);
return 0;
}
int
sunxi_ccu_nm_set_parent(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk, const char *name)
{
struct sunxi_ccu_nm *nm = &clk->u.nm;
uint32_t val;
u_int index;
KASSERT(clk->type == SUNXI_CCU_NM);
if (nm->sel == 0)
return ENODEV;
for (index = 0; index < nm->nparents; index++) {
if (nm->parents[index] != NULL &&
strcmp(nm->parents[index], name) == 0)
break;
}
if (index == nm->nparents)
return EINVAL;
val = CCU_READ(sc, nm->reg);
val &= ~nm->sel;
val |= __SHIFTIN(index, nm->sel);
CCU_WRITE(sc, nm->reg, val);
return 0;
}
const char *
sunxi_ccu_nm_get_parent(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk)
{
struct sunxi_ccu_nm *nm = &clk->u.nm;
u_int index;
uint32_t val;
KASSERT(clk->type == SUNXI_CCU_NM);
val = CCU_READ(sc, nm->reg);
index = __SHIFTOUT(val, nm->sel);
return nm->parents[index];
}

View File

@ -0,0 +1,136 @@
/* $NetBSD: sunxi_ccu_prediv.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_prediv.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <dev/clk/clk_backend.h>
#include <arm/sunxi/sunxi_ccu.h>
u_int
sunxi_ccu_prediv_get_rate(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk)
{
struct sunxi_ccu_prediv *prediv = &clk->u.prediv;
struct clk *clkp, *clkp_parent;
u_int rate, pre, div, sel;
uint32_t val;
KASSERT(clk->type == SUNXI_CCU_PREDIV);
clkp = &clk->base;
clkp_parent = clk_get_parent(clkp);
if (clkp_parent == NULL)
return 0;
rate = clk_get_rate(clkp_parent);
if (rate == 0)
return 0;
val = CCU_READ(sc, prediv->reg);
if (prediv->prediv)
pre = __SHIFTOUT(val, prediv->prediv);
else
pre = 0;
if (prediv->div)
div = __SHIFTOUT(val, prediv->div);
else
div = 0;
sel = __SHIFTOUT(val, prediv->sel);
if (prediv->flags & SUNXI_CCU_PREDIV_POWER_OF_TWO)
div = 1 << div;
else
div++;
pre++;
if (prediv->flags & SUNXI_CCU_PREDIV_DIVIDE_BY_TWO)
pre *= 2;
if (prediv->prediv_sel & __BIT(sel))
return rate / pre / div;
else
return rate / div;
}
int
sunxi_ccu_prediv_set_rate(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk, u_int new_rate)
{
return EINVAL;
}
int
sunxi_ccu_prediv_set_parent(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk, const char *name)
{
struct sunxi_ccu_prediv *prediv = &clk->u.prediv;
uint32_t val;
u_int index;
KASSERT(clk->type == SUNXI_CCU_PREDIV);
if (prediv->sel == 0)
return ENODEV;
for (index = 0; index < prediv->nparents; index++) {
if (prediv->parents[index] != NULL &&
strcmp(prediv->parents[index], name) == 0)
break;
}
if (index == prediv->nparents)
return EINVAL;
val = CCU_READ(sc, prediv->reg);
val &= ~prediv->sel;
val |= __SHIFTIN(index, prediv->sel);
CCU_WRITE(sc, prediv->reg, val);
return 0;
}
const char *
sunxi_ccu_prediv_get_parent(struct sunxi_ccu_softc *sc,
struct sunxi_ccu_clk *clk)
{
struct sunxi_ccu_prediv *prediv = &clk->u.prediv;
u_int index;
uint32_t val;
KASSERT(clk->type == SUNXI_CCU_PREDIV);
val = CCU_READ(sc, prediv->reg);
index = __SHIFTOUT(val, prediv->sel);
return prediv->parents[index];
}

View File

@ -0,0 +1,178 @@
/* $NetBSD: sunxi_com.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(1, "$NetBSD: sunxi_com.c,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/termios.h>
#include <dev/ic/comvar.h>
#include <dev/fdt/fdtvar.h>
static int sunxi_com_match(device_t, cfdata_t, void *);
static void sunxi_com_attach(device_t, device_t, void *);
static const char * const compatible[] = {
"snps,dw-apb-uart",
NULL
};
struct sunxi_com_softc {
struct com_softc ssc_sc;
void *ssc_ih;
struct clk *ssc_clk;
struct fdtbus_reset *ssc_rst;
};
CFATTACH_DECL_NEW(sunxi_com, sizeof(struct sunxi_com_softc),
sunxi_com_match, sunxi_com_attach, NULL, NULL);
static int
sunxi_com_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
sunxi_com_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_com_softc * const ssc = device_private(self);
struct com_softc * const sc = &ssc->ssc_sc;
struct fdt_attach_args * const faa = aux;
bus_space_handle_t bsh;
bus_space_tag_t bst;
char intrstr[128];
bus_addr_t addr;
bus_size_t size;
u_int reg_shift;
int error;
if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
if (of_getprop_uint32(faa->faa_phandle, "reg-shift", &reg_shift)) {
/* missing or bad reg-shift property, assume 2 */
bst = faa->faa_a4x_bst;
} else {
if (reg_shift == 2) {
bst = faa->faa_a4x_bst;
} else if (reg_shift == 0) {
bst = faa->faa_bst;
} else {
aprint_error(": unsupported reg-shift value %d\n",
reg_shift);
return;
}
}
sc->sc_dev = self;
ssc->ssc_clk = fdtbus_clock_get_index(faa->faa_phandle, 0);
ssc->ssc_rst = fdtbus_reset_get_index(faa->faa_phandle, 0);
if (ssc->ssc_clk == NULL) {
aprint_error(": couldn't get frequency\n");
return;
}
sc->sc_frequency = clk_get_rate(ssc->ssc_clk);
sc->sc_type = COM_TYPE_NORMAL;
error = bus_space_map(bst, addr, size, 0, &bsh);
if (error) {
aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
return;
}
COM_INIT_REGS(sc->sc_regs, bst, bsh, addr);
com_attach_subr(sc);
aprint_naive("\n");
if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
aprint_error_dev(self, "failed to decode interrupt\n");
return;
}
ssc->ssc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_SERIAL,
FDT_INTR_MPSAFE, comintr, sc);
if (ssc->ssc_ih == NULL) {
aprint_error_dev(self, "failed to establish interrupt on %s\n",
intrstr);
}
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
}
/*
* Console support
*/
static int
sunxi_com_console_match(int phandle)
{
return of_match_compatible(phandle, compatible);
}
static void
sunxi_com_console_consinit(struct fdt_attach_args *faa, u_int uart_freq)
{
const int phandle = faa->faa_phandle;
bus_space_tag_t bst = faa->faa_a4x_bst;
bus_addr_t addr;
tcflag_t flags;
int speed;
fdtbus_get_reg(phandle, 0, &addr, NULL);
speed = fdtbus_get_stdout_speed();
if (speed < 0)
speed = 115200; /* default */
flags = fdtbus_get_stdout_flags();
if (comcnattach(bst, addr, speed, uart_freq, COM_TYPE_NORMAL, flags))
panic("Cannot initialize sunxi com console");
}
static const struct fdt_console sunxi_com_console = {
.match = sunxi_com_console_match,
.consinit = sunxi_com_console_consinit,
};
FDT_CONSOLE(sunxi_com, &sunxi_com_console);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,184 @@
/*-
* Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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$
*/
/*
* Allwinner Gigabit Ethernet
*/
#ifndef __SUNXI_EMAC_H__
#define __SUNXI_EMAC_H__
#define EMAC_BASIC_CTL_0 0x00
#define BASIC_CTL_SPEED (0x3 << 2)
#define BASIC_CTL_SPEED_SHIFT 2
#define BASIC_CTL_SPEED_1000 0
#define BASIC_CTL_SPEED_10 2
#define BASIC_CTL_SPEED_100 3
#define BASIC_CTL_LOOPBACK (1 << 1)
#define BASIC_CTL_DUPLEX (1 << 0)
#define EMAC_BASIC_CTL_1 0x04
#define BASIC_CTL_BURST_LEN (0x3f << 24)
#define BASIC_CTL_BURST_LEN_SHIFT 24
#define BASIC_CTL_RX_TX_PRI (1 << 1)
#define BASIC_CTL_SOFT_RST (1 << 0)
#define EMAC_INT_STA 0x08
#define RX_BUF_UA_INT (1 << 10)
#define RX_INT (1 << 8)
#define TX_UNDERFLOW_INT (1 << 4)
#define TX_BUF_UA_INT (1 << 2)
#define TX_DMA_STOPPED_INT (1 << 1)
#define TX_INT (1 << 0)
#define EMAC_INT_EN 0x0c
#define RX_BUF_UA_INT_EN (1 << 10)
#define RX_INT_EN (1 << 8)
#define TX_UNDERFLOW_INT_EN (1 << 4)
#define TX_BUF_UA_INT_EN (1 << 2)
#define TX_DMA_STOPPED_INT_EN (1 << 1)
#define TX_INT_EN (1 << 0)
#define EMAC_TX_CTL_0 0x10
#define TX_EN (1 << 31)
#define EMAC_TX_CTL_1 0x14
#define TX_DMA_START (1 << 31)
#define TX_DMA_EN (1 << 30)
#define TX_NEXT_FRAME (1 << 2)
#define TX_MD (1 << 1)
#define FLUSH_TX_FIFO (1 << 0)
#define EMAC_TX_FLOW_CTL 0x1c
#define PAUSE_TIME (0xffff << 4)
#define PAUSE_TIME_SHIFT 4
#define TX_FLOW_CTL_EN (1 << 0)
#define EMAC_TX_DMA_LIST 0x20
#define EMAC_RX_CTL_0 0x24
#define RX_EN (1 << 31)
#define JUMBO_FRM_EN (1 << 29)
#define STRIP_FCS (1 << 28)
#define CHECK_CRC (1 << 27)
#define RX_FLOW_CTL_EN (1 << 16)
#define EMAC_RX_CTL_1 0x28
#define RX_DMA_START (1 << 31)
#define RX_DMA_EN (1 << 30)
#define RX_MD (1 << 1)
#define EMAC_RX_DMA_LIST 0x34
#define EMAC_RX_FRM_FLT 0x38
#define DIS_ADDR_FILTER (1 << 31)
#define DIS_BROADCAST (1 << 17)
#define RX_ALL_MULTICAST (1 << 16)
#define CTL_FRM_FILTER (0x3 << 12)
#define CTL_FRM_FILTER_SHIFT 12
#define HASH_MULTICAST (1 << 9)
#define HASH_UNICAST (1 << 8)
#define SA_FILTER_EN (1 << 6)
#define SA_INV_FILTER (1 << 5)
#define DA_INV_FILTER (1 << 4)
#define FLT_MD (1 << 1)
#define RX_ALL (1 << 0)
#define EMAC_RX_HASH_0 0x40
#define EMAC_RX_HASH_1 0x44
#define EMAC_MII_CMD 0x48
#define MDC_DIV_RATIO_M (0x7 << 20)
#define MDC_DIV_RATIO_M_16 0
#define MDC_DIV_RATIO_M_32 1
#define MDC_DIV_RATIO_M_64 2
#define MDC_DIV_RATIO_M_128 3
#define MDC_DIV_RATIO_M_SHIFT 20
#define PHY_ADDR (0x1f << 12)
#define PHY_ADDR_SHIFT 12
#define PHY_REG_ADDR (0x1f << 4)
#define PHY_REG_ADDR_SHIFT 4
#define MII_WR (1 << 1)
#define MII_BUSY (1 << 0)
#define EMAC_MII_DATA 0x4c
#define EMAC_ADDR_HIGH(n) (0x50 + (n) * 8)
#define EMAC_ADDR_LOW(n) (0x54 + (n) * 8)
#define EMAC_TX_DMA_STA 0x80
#define EMAC_TX_DMA_CUR_DESC 0x84
#define EMAC_TX_DMA_CUR_BUF 0x88
#define EMAC_RX_DMA_STA 0xc0
#define EMAC_RX_DMA_CUR_DESC 0xc4
#define EMAC_RX_DMA_CUR_BUF 0xc8
#define EMAC_RGMII_STA 0xd0
struct sunxi_emac_desc {
uint32_t status;
/* Transmit */
#define TX_DESC_CTL (1 << 31)
#define TX_HEADER_ERR (1 << 16)
#define TX_LENGTH_ERR (1 << 14)
#define TX_PAYLOAD_ERR (1 << 12)
#define TX_CRS_ERR (1 << 10)
#define TX_COL_ERR_0 (1 << 9)
#define TX_COL_ERR_1 (1 << 8)
#define TX_COL_CNT (0xf << 3)
#define TX_COL_CNT_SHIFT 3
#define TX_DEFER_ERR (1 << 2)
#define TX_UNDERFLOW_ERR (1 << 1)
#define TX_DEFER (1 << 0)
/* Receive */
#define RX_DESC_CTL (1 << 31)
#define RX_DAF_FAIL (1 << 30)
#define RX_FRM_LEN (0x3fff << 16)
#define RX_FRM_LEN_SHIFT 16
#define RX_NO_ENOUGH_BUF_ERR (1 << 14)
#define RX_SAF_FAIL (1 << 13)
#define RX_OVERFLOW_ERR (1 << 11)
#define RX_FIR_DESC (1 << 9)
#define RX_LAST_DESC (1 << 8)
#define RX_HEADER_ERR (1 << 7)
#define RX_COL_ERR (1 << 6)
#define RX_FRM_TYPE (1 << 5)
#define RX_LENGTH_ERR (1 << 4)
#define RX_PHY_ERR (1 << 3)
#define RX_CRC_ERR (1 << 1)
#define RX_PAYLOAD_ERR (1 << 0)
uint32_t size;
/* Transmit */
#define TX_INT_CTL (1 << 31)
#define TX_LAST_DESC (1 << 30)
#define TX_FIR_DESC (1 << 29)
#define TX_CHECKSUM_CTL (0x3 << 27)
#define TX_CHECKSUM_CTL_IP 1
#define TX_CHECKSUM_CTL_NO_PSE 2
#define TX_CHECKSUM_CTL_FULL 3
#define TX_CHECKSUM_CTL_SHIFT 27
#define TX_CRC_CTL (1 << 26)
#define TX_BUF_SIZE (0xfff << 0)
#define TX_BUF_SIZE_SHIFT 0
/* Receive */
#define RX_INT_CTL (1 << 31)
#define RX_BUF_SIZE (0xfff << 0)
#define RX_BUF_SIZE_SHIFT 0
uint32_t addr;
uint32_t next;
} __packed __aligned(CACHE_LINE_SIZE);
__CTASSERT(sizeof(struct sunxi_emac_desc) == CACHE_LINE_SIZE);
#endif /* !__SUNXI_EMAC_H__ */

View File

@ -0,0 +1,277 @@
/* $NetBSD: sunxi_gates.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_gates.c,v 1.1.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <sys/kmem.h>
#include <dev/fdt/fdtvar.h>
#include <dev/clk/clk_backend.h>
#define GATE_REG(index) (((index) / 32) * 4)
#define GATE_MASK(index) __BIT((index) % 32)
static const char * compatible[] = {
"allwinner,sun4i-a10-gates-clk",
NULL
};
struct sunxi_gate {
struct clk base;
u_int index;
TAILQ_ENTRY(sunxi_gate) gates;
};
struct sunxi_gates_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
int sc_phandle;
struct clk_domain sc_clkdom;
TAILQ_HEAD(, sunxi_gate) sc_gates;
};
#define GATE_READ(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define GATE_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
static struct clk *
sunxi_gates_clock_decode(device_t dev, const void *data, size_t len)
{
struct sunxi_gates_softc * const sc = device_private(dev);
struct sunxi_gate *gate;
if (len != 4)
return NULL;
const u_int index = be32dec(data);
TAILQ_FOREACH(gate, &sc->sc_gates, gates)
if (gate->index == index)
return &gate->base;
return NULL;
}
static const struct fdtbus_clock_controller_func sunxi_gates_fdtclock_funcs = {
.decode = sunxi_gates_clock_decode,
};
static struct clk *
sunxi_gates_clock_get(void *priv, const char *name)
{
struct sunxi_gates_softc * const sc = priv;
struct sunxi_gate *gate;
TAILQ_FOREACH(gate, &sc->sc_gates, gates)
if (strcmp(gate->base.name, name) == 0)
return &gate->base;
return NULL;
}
static void
sunxi_gates_clock_put(void *priv, struct clk *clk)
{
}
static u_int
sunxi_gates_clock_get_rate(void *priv, struct clk *clkp)
{
struct sunxi_gates_softc * const sc = priv;
struct sunxi_gate *gate = (struct sunxi_gate *)clkp;
struct clk *clkp_parent;
clkp_parent = clk_get_parent(clkp);
if (clkp_parent == NULL)
return 0;
const bus_size_t gate_reg = GATE_REG(gate->index);
const uint32_t gate_mask = GATE_MASK(gate->index);
if ((GATE_READ(sc, gate_reg) & gate_mask) == 0)
return 0;
return clk_get_rate(clkp_parent);
}
static int
sunxi_gates_clock_enable(void *priv, struct clk *clkp)
{
struct sunxi_gates_softc * const sc = priv;
struct sunxi_gate *gate = (struct sunxi_gate *)clkp;
uint32_t val;
const bus_size_t gate_reg = GATE_REG(gate->index);
const uint32_t gate_mask = GATE_MASK(gate->index);
val = GATE_READ(sc, gate_reg);
val |= gate_mask;
GATE_WRITE(sc, gate_reg, val);
return 0;
}
static int
sunxi_gates_clock_disable(void *priv, struct clk *clkp)
{
struct sunxi_gates_softc * const sc = priv;
struct sunxi_gate *gate = (struct sunxi_gate *)clkp;
uint32_t val;
const bus_size_t gate_reg = GATE_REG(gate->index);
const uint32_t gate_mask = GATE_MASK(gate->index);
val = GATE_READ(sc, gate_reg);
val &= ~gate_mask;
GATE_WRITE(sc, gate_reg, val);
return 0;
}
static struct clk *
sunxi_gates_clock_get_parent(void *priv, struct clk *clkp)
{
struct sunxi_gates_softc * const sc = priv;
return fdtbus_clock_get_index(sc->sc_phandle, 0);
}
static const struct clk_funcs sunxi_gates_clock_funcs = {
.get = sunxi_gates_clock_get,
.put = sunxi_gates_clock_put,
.get_rate = sunxi_gates_clock_get_rate,
.enable = sunxi_gates_clock_enable,
.disable = sunxi_gates_clock_disable,
.get_parent = sunxi_gates_clock_get_parent,
};
static void
sunxi_gates_print(struct sunxi_gates_softc *sc)
{
struct sunxi_gate *gate;
struct clk *clkp_parent;
TAILQ_FOREACH(gate, &sc->sc_gates, gates) {
clkp_parent = clk_get_parent(&gate->base);
aprint_debug_dev(sc->sc_dev,
"%3d %-12s %2s %-12s %-7s ",
gate->index,
gate->base.name,
clkp_parent ? "<-" : "",
clkp_parent ? clkp_parent->name : "",
"gate");
aprint_debug("%10d Hz\n", clk_get_rate(&gate->base));
}
}
static int
sunxi_gates_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
sunxi_gates_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_gates_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
struct sunxi_gate *gate;
const u_int *indices;
bus_addr_t addr;
bus_size_t size;
int len, i;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
sc->sc_dev = self;
sc->sc_phandle = phandle;
sc->sc_bst = faa->faa_bst;
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
aprint_error(": couldn't map registers\n");
return;
}
TAILQ_INIT(&sc->sc_gates);
aprint_naive("\n");
aprint_normal("\n");
sc->sc_clkdom.funcs = &sunxi_gates_clock_funcs;
sc->sc_clkdom.priv = sc;
indices = fdtbus_get_prop(phandle, "clock-indices", &len);
if (indices == NULL) {
aprint_error_dev(self, "no clock-indices property\n");
return;
}
for (i = 0;
len >= sizeof(u_int);
len -= sizeof(u_int), i++, indices++) {
const u_int index = be32dec(indices);
const char *name = fdtbus_get_string_index(phandle,
"clock-output-names", i);
if (name == NULL) {
aprint_error_dev(self, "no name for clk index %d\n",
index);
continue;
}
gate = kmem_zalloc(sizeof(*gate), KM_SLEEP);
gate->base.domain = &sc->sc_clkdom;
gate->base.name = name;
gate->index = index;
TAILQ_INSERT_TAIL(&sc->sc_gates, gate, gates);
}
fdtbus_register_clock_controller(sc->sc_dev, phandle,
&sunxi_gates_fdtclock_funcs);
sunxi_gates_print(sc);
}
CFATTACH_DECL_NEW(sunxi_gates, sizeof(struct sunxi_gates_softc),
sunxi_gates_match, sunxi_gates_attach, NULL, NULL);

View File

@ -0,0 +1,556 @@
/* $NetBSD: sunxi_gpio.c,v 1.8.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include "opt_soc.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_gpio.c,v 1.8.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/mutex.h>
#include <sys/kmem.h>
#include <sys/gpio.h>
#include <dev/fdt/fdtvar.h>
#include <dev/gpio/gpiovar.h>
#include <arm/sunxi/sunxi_gpio.h>
#define SUNXI_GPIO_PORT(port) (0x24 * (port))
#define SUNXI_GPIO_CFG(port, pin) (SUNXI_GPIO_PORT(port) + 0x00 + (0x4 * ((pin) / 8)))
#define SUNXI_GPIO_CFG_PINMASK(pin) (0x7 << (((pin) % 8) * 4))
#define SUNXI_GPIO_DATA(port) (SUNXI_GPIO_PORT(port) + 0x10)
#define SUNXI_GPIO_DRV(port, pin) (SUNXI_GPIO_PORT(port) + 0x14 + (0x4 * ((pin) / 16)))
#define SUNXI_GPIO_DRV_PINMASK(pin) (0x3 << (((pin) % 16) * 2))
#define SUNXI_GPIO_PULL(port, pin) (SUNXI_GPIO_PORT(port) + 0x1c + (0x4 * ((pin) / 16)))
#define SUNXI_GPIO_PULL_DISABLE 0
#define SUNXI_GPIO_PULL_UP 1
#define SUNXI_GPIO_PULL_DOWN 2
#define SUNXI_GPIO_PULL_PINMASK(pin) (0x3 << (((pin) % 16) * 2))
static const struct of_compat_data compat_data[] = {
#ifdef SOC_SUN6I_A31
{ "allwinner,sun6i-a31-pinctrl", (uintptr_t)&sun6i_a31_padconf },
{ "allwinner,sun6i-a31-r-pinctrl", (uintptr_t)&sun6i_a31_r_padconf },
#endif
#ifdef SOC_SUN8I_A83T
{ "allwinner,sun8i-a83t-pinctrl", (uintptr_t)&sun8i_a83t_padconf },
{ "allwinner,sun8i-a83t-r-pinctrl", (uintptr_t)&sun8i_a83t_r_padconf },
#endif
#ifdef SOC_SUN8I_H3
{ "allwinner,sun8i-h3-pinctrl", (uintptr_t)&sun8i_h3_padconf },
{ "allwinner,sun8i-h3-r-pinctrl", (uintptr_t)&sun8i_h3_r_padconf },
#endif
{ NULL }
};
struct sunxi_gpio_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
const struct sunxi_gpio_padconf *sc_padconf;
kmutex_t sc_lock;
struct gpio_chipset_tag sc_gp;
gpio_pin_t *sc_pins;
device_t sc_gpiodev;
};
struct sunxi_gpio_pin {
struct sunxi_gpio_softc *pin_sc;
const struct sunxi_gpio_pins *pin_def;
int pin_flags;
bool pin_actlo;
};
#define GPIO_READ(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define GPIO_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
static int sunxi_gpio_match(device_t, cfdata_t, void *);
static void sunxi_gpio_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(sunxi_gpio, sizeof(struct sunxi_gpio_softc),
sunxi_gpio_match, sunxi_gpio_attach, NULL, NULL);
static const struct sunxi_gpio_pins *
sunxi_gpio_lookup(struct sunxi_gpio_softc *sc, uint8_t port, uint8_t pin)
{
const struct sunxi_gpio_pins *pin_def;
u_int n;
for (n = 0; n < sc->sc_padconf->npins; n++) {
pin_def = &sc->sc_padconf->pins[n];
if (pin_def->port == port && pin_def->pin == pin)
return pin_def;
}
return NULL;
}
static const struct sunxi_gpio_pins *
sunxi_gpio_lookup_byname(struct sunxi_gpio_softc *sc, const char *name)
{
const struct sunxi_gpio_pins *pin_def;
u_int n;
for (n = 0; n < sc->sc_padconf->npins; n++) {
pin_def = &sc->sc_padconf->pins[n];
if (strcmp(pin_def->name, name) == 0)
return pin_def;
}
return NULL;
}
static int
sunxi_gpio_setfunc(struct sunxi_gpio_softc *sc,
const struct sunxi_gpio_pins *pin_def, const char *func)
{
uint32_t cfg;
u_int n;
KASSERT(mutex_owned(&sc->sc_lock));
const bus_size_t cfg_reg = SUNXI_GPIO_CFG(pin_def->port, pin_def->pin);
const uint32_t cfg_mask = SUNXI_GPIO_CFG_PINMASK(pin_def->pin);
for (n = 0; n < SUNXI_GPIO_MAXFUNC; n++) {
if (pin_def->functions[n] == NULL)
continue;
if (strcmp(pin_def->functions[n], func) == 0) {
cfg = GPIO_READ(sc, cfg_reg);
cfg &= ~cfg_mask;
cfg |= __SHIFTIN(n, cfg_mask);
#ifdef SUNXI_GPIO_DEBUG
device_printf(sc->sc_dev, "P%c%02d cfg %08x -> %08x\n",
pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, cfg_reg), cfg);
#endif
GPIO_WRITE(sc, cfg_reg, cfg);
return 0;
}
}
/* Function not found */
device_printf(sc->sc_dev, "function '%s' not supported on P%c%02d\n",
func, pin_def->port + 'A', pin_def->pin);
return ENXIO;
}
static int
sunxi_gpio_setpull(struct sunxi_gpio_softc *sc,
const struct sunxi_gpio_pins *pin_def, int flags)
{
uint32_t pull;
KASSERT(mutex_owned(&sc->sc_lock));
const bus_size_t pull_reg = SUNXI_GPIO_PULL(pin_def->port, pin_def->pin);
const uint32_t pull_mask = SUNXI_GPIO_PULL_PINMASK(pin_def->pin);
pull = GPIO_READ(sc, pull_reg);
pull &= ~pull_mask;
if (flags & GPIO_PIN_PULLUP)
pull |= __SHIFTIN(SUNXI_GPIO_PULL_UP, pull_mask);
else if (flags & GPIO_PIN_PULLDOWN)
pull |= __SHIFTIN(SUNXI_GPIO_PULL_DOWN, pull_mask);
else
pull |= __SHIFTIN(SUNXI_GPIO_PULL_DISABLE, pull_mask);
#ifdef SUNXI_GPIO_DEBUG
device_printf(sc->sc_dev, "P%c%02d pull %08x -> %08x\n",
pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, pull_reg), pull);
#endif
GPIO_WRITE(sc, pull_reg, pull);
return 0;
}
static int
sunxi_gpio_setdrv(struct sunxi_gpio_softc *sc,
const struct sunxi_gpio_pins *pin_def, int drive_strength)
{
uint32_t drv;
KASSERT(mutex_owned(&sc->sc_lock));
if (drive_strength < 10 || drive_strength > 40)
return EINVAL;
const bus_size_t drv_reg = SUNXI_GPIO_DRV(pin_def->port, pin_def->pin);
const uint32_t drv_mask = SUNXI_GPIO_DRV_PINMASK(pin_def->pin);
drv = GPIO_READ(sc, drv_reg);
drv &= ~drv_mask;
drv |= __SHIFTIN((drive_strength / 10) - 1, drv_mask);
#ifdef SUNXI_GPIO_DEBUG
device_printf(sc->sc_dev, "P%c%02d drv %08x -> %08x\n",
pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, drv_reg), drv);
#endif
GPIO_WRITE(sc, drv_reg, drv);
return 0;
}
static int
sunxi_gpio_ctl(struct sunxi_gpio_softc *sc, const struct sunxi_gpio_pins *pin_def,
int flags)
{
KASSERT(mutex_owned(&sc->sc_lock));
if (flags & GPIO_PIN_INPUT)
return sunxi_gpio_setfunc(sc, pin_def, "gpio_in");
if (flags & GPIO_PIN_OUTPUT)
return sunxi_gpio_setfunc(sc, pin_def, "gpio_out");
return EINVAL;
}
static void *
sunxi_gpio_acquire(device_t dev, const void *data, size_t len, int flags)
{
struct sunxi_gpio_softc * const sc = device_private(dev);
const struct sunxi_gpio_pins *pin_def;
struct sunxi_gpio_pin *gpin;
const u_int *gpio = data;
int error;
if (len != 16)
return NULL;
const uint8_t port = be32toh(gpio[1]) & 0xff;
const uint8_t pin = be32toh(gpio[2]) & 0xff;
const bool actlo = be32toh(gpio[3]) & 1;
pin_def = sunxi_gpio_lookup(sc, port, pin);
if (pin_def == NULL)
return NULL;
mutex_enter(&sc->sc_lock);
error = sunxi_gpio_ctl(sc, pin_def, flags);
mutex_exit(&sc->sc_lock);
if (error != 0)
return NULL;
gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP);
gpin->pin_sc = sc;
gpin->pin_def = pin_def;
gpin->pin_flags = flags;
gpin->pin_actlo = actlo;
return gpin;
}
static void
sunxi_gpio_release(device_t dev, void *priv)
{
struct sunxi_gpio_pin *pin = priv;
sunxi_gpio_ctl(pin->pin_sc, pin->pin_def, GPIO_PIN_INPUT);
kmem_free(pin, sizeof(*pin));
}
static int
sunxi_gpio_read(device_t dev, void *priv, bool raw)
{
struct sunxi_gpio_softc * const sc = device_private(dev);
struct sunxi_gpio_pin *pin = priv;
const struct sunxi_gpio_pins *pin_def = pin->pin_def;
uint32_t data;
int val;
KASSERT(sc == pin->pin_sc);
const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
const uint32_t data_mask = __BIT(pin_def->pin);
/* No lock required for reads */
data = GPIO_READ(sc, data_reg);
val = __SHIFTOUT(data, data_mask);
if (!raw && pin->pin_actlo)
val = !val;
#ifdef SUNXI_GPIO_DEBUG
device_printf(dev, "P%c%02d rd %08x (%d %d)\n",
pin_def->port + 'A', pin_def->pin, data,
__SHIFTOUT(val, data_mask), val);
#endif
return val;
}
static void
sunxi_gpio_write(device_t dev, void *priv, int val, bool raw)
{
struct sunxi_gpio_softc * const sc = device_private(dev);
struct sunxi_gpio_pin *pin = priv;
const struct sunxi_gpio_pins *pin_def = pin->pin_def;
uint32_t data;
KASSERT(sc == pin->pin_sc);
const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
const uint32_t data_mask = __BIT(pin_def->pin);
if (!raw && pin->pin_actlo)
val = !val;
mutex_enter(&sc->sc_lock);
data = GPIO_READ(sc, data_reg);
data &= ~data_mask;
data |= __SHIFTIN(val, data_mask);
#ifdef SUNXI_GPIO_DEBUG
device_printf(dev, "P%c%02d wr %08x -> %08x\n",
pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, data_reg), data);
#endif
GPIO_WRITE(sc, data_reg, data);
mutex_exit(&sc->sc_lock);
}
static struct fdtbus_gpio_controller_func sunxi_gpio_funcs = {
.acquire = sunxi_gpio_acquire,
.release = sunxi_gpio_release,
.read = sunxi_gpio_read,
.write = sunxi_gpio_write,
};
static int
sunxi_pinctrl_set_config(device_t dev, const void *data, size_t len)
{
struct sunxi_gpio_softc * const sc = device_private(dev);
const struct sunxi_gpio_pins *pin_def;
u_int drive_strength;
if (len != 4)
return -1;
const int phandle = fdtbus_get_phandle_from_native(be32dec(data));
/*
* Required: pins, function
* Optional: bias-disable, bias-pull-up, bias-pull-down, drive-strength
*/
const char *function = fdtbus_get_string(phandle, "function");
if (function == NULL)
return -1;
int pins_len = OF_getproplen(phandle, "pins");
if (pins_len <= 0)
return -1;
const char *pins = fdtbus_get_string(phandle, "pins");
mutex_enter(&sc->sc_lock);
for (pins = fdtbus_get_string(phandle, "pins");
pins_len > 0;
pins_len -= strlen(pins) + 1, pins += strlen(pins) + 1) {
pin_def = sunxi_gpio_lookup_byname(sc, pins);
if (pin_def == NULL) {
aprint_error_dev(dev, "unknown pin name '%s'\n", pins);
continue;
}
if (sunxi_gpio_setfunc(sc, pin_def, function) != 0)
continue;
if (of_hasprop(phandle, "bias-disable"))
sunxi_gpio_setpull(sc, pin_def, 0);
else if (of_hasprop(phandle, "bias-pull-up"))
sunxi_gpio_setpull(sc, pin_def, GPIO_PIN_PULLUP);
else if (of_hasprop(phandle, "bias-pull-down"))
sunxi_gpio_setpull(sc, pin_def, GPIO_PIN_PULLDOWN);
if (of_getprop_uint32(phandle, "drive-strength", &drive_strength) == 0)
sunxi_gpio_setdrv(sc, pin_def, drive_strength);
}
mutex_exit(&sc->sc_lock);
return 0;
}
static struct fdtbus_pinctrl_controller_func sunxi_pinctrl_funcs = {
.set_config = sunxi_pinctrl_set_config,
};
static int
sunxi_gpio_pin_read(void *priv, int pin)
{
struct sunxi_gpio_softc * const sc = priv;
const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin];
uint32_t data;
int val;
KASSERT(pin < sc->sc_padconf->npins);
const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
const uint32_t data_mask = __BIT(pin_def->pin);
/* No lock required for reads */
data = GPIO_READ(sc, data_reg);
val = __SHIFTOUT(data, data_mask);
return val;
}
static void
sunxi_gpio_pin_write(void *priv, int pin, int val)
{
struct sunxi_gpio_softc * const sc = priv;
const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin];
uint32_t data;
KASSERT(pin < sc->sc_padconf->npins);
const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port);
const uint32_t data_mask = __BIT(pin_def->pin);
mutex_enter(&sc->sc_lock);
data = GPIO_READ(sc, data_reg);
if (val)
data |= data_mask;
else
data &= ~data_mask;
GPIO_WRITE(sc, data_reg, data);
mutex_exit(&sc->sc_lock);
}
static void
sunxi_gpio_pin_ctl(void *priv, int pin, int flags)
{
struct sunxi_gpio_softc * const sc = priv;
const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin];
KASSERT(pin < sc->sc_padconf->npins);
mutex_enter(&sc->sc_lock);
sunxi_gpio_ctl(sc, pin_def, flags);
sunxi_gpio_setpull(sc, pin_def, flags);
mutex_exit(&sc->sc_lock);
}
static void
sunxi_gpio_attach_ports(struct sunxi_gpio_softc *sc)
{
const struct sunxi_gpio_pins *pin_def;
struct gpio_chipset_tag *gp = &sc->sc_gp;
struct gpiobus_attach_args gba;
u_int pin;
gp->gp_cookie = sc;
gp->gp_pin_read = sunxi_gpio_pin_read;
gp->gp_pin_write = sunxi_gpio_pin_write;
gp->gp_pin_ctl = sunxi_gpio_pin_ctl;
const u_int npins = sc->sc_padconf->npins;
sc->sc_pins = kmem_zalloc(sizeof(*sc->sc_pins) * npins, KM_SLEEP);
for (pin = 0; pin < sc->sc_padconf->npins; pin++) {
pin_def = &sc->sc_padconf->pins[pin];
sc->sc_pins[pin].pin_num = pin;
sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
sc->sc_pins[pin].pin_state = sunxi_gpio_pin_read(sc, pin);
strlcpy(sc->sc_pins[pin].pin_defname, pin_def->name,
sizeof(sc->sc_pins[pin].pin_defname));
}
memset(&gba, 0, sizeof(gba));
gba.gba_gc = gp;
gba.gba_pins = sc->sc_pins;
gba.gba_npins = npins;
sc->sc_gpiodev = config_found_ia(sc->sc_dev, "gpiobus", &gba, NULL);
}
static int
sunxi_gpio_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compat_data(faa->faa_phandle, compat_data);
}
static void
sunxi_gpio_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_gpio_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
struct fdtbus_reset *rst;
struct clk *clk;
bus_addr_t addr;
bus_size_t size;
int child;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
if ((clk = fdtbus_clock_get_index(phandle, 0)) != NULL)
if (clk_enable(clk) != 0) {
aprint_error(": couldn't enable clock\n");
return;
}
if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL)
if (fdtbus_reset_deassert(rst) != 0) {
aprint_error(": couldn't de-assert reset\n");
return;
}
sc->sc_dev = self;
sc->sc_bst = faa->faa_bst;
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
aprint_error(": couldn't map registers\n");
return;
}
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
sc->sc_padconf = (void *)of_search_compatible(phandle, compat_data)->data;
aprint_naive("\n");
aprint_normal(": PIO\n");
fdtbus_register_gpio_controller(self, phandle, &sunxi_gpio_funcs);
for (child = OF_child(phandle); child; child = OF_peer(child)) {
if (!of_hasprop(child, "function") || !of_hasprop(child, "pins"))
continue;
fdtbus_register_pinctrl_config(self, child, &sunxi_pinctrl_funcs);
}
fdtbus_pinctrl_configure();
sunxi_gpio_attach_ports(sc);
}

View File

@ -0,0 +1,68 @@
/* $NetBSD: sunxi_gpio.h,v 1.3.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* Copyright (c) 2016 Emmanuel Vadot <manu@bidouilliste.com>
* 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$
*/
#ifndef _ARM_SUNXI_GPIO_H
#define _ARM_SUNXI_GPIO_H
#include "opt_soc.h"
#define SUNXI_GPIO_MAXFUNC 8
struct sunxi_gpio_pins {
const char *name;
uint8_t port;
uint8_t pin;
const char *functions[SUNXI_GPIO_MAXFUNC];
uint8_t eint_func;
uint8_t eint_num;
};
struct sunxi_gpio_padconf {
uint32_t npins;
const struct sunxi_gpio_pins *pins;
};
#ifdef SOC_SUN6I_A31
extern const struct sunxi_gpio_padconf sun6i_a31_padconf;
extern const struct sunxi_gpio_padconf sun6i_a31_r_padconf;
#endif
#ifdef SOC_SUN8I_A83T
extern const struct sunxi_gpio_padconf sun8i_a83t_padconf;
extern const struct sunxi_gpio_padconf sun8i_a83t_r_padconf;
#endif
#ifdef SOC_SUN8I_H3
extern const struct sunxi_gpio_padconf sun8i_h3_padconf;
extern const struct sunxi_gpio_padconf sun8i_h3_r_padconf;
#endif
#endif /* _ARM_SUNXI_GPIO_H */

View File

@ -0,0 +1,857 @@
/* $NetBSD: sunxi_mmc.c,v 1.3.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2014-2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_mmc.c,v 1.3.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/gpio.h>
#include <dev/sdmmc/sdmmcvar.h>
#include <dev/sdmmc/sdmmcchip.h>
#include <dev/sdmmc/sdmmc_ioreg.h>
#include <dev/fdt/fdtvar.h>
#include <arm/sunxi/sunxi_mmc.h>
#define SUNXI_MMC_NDESC 16
#define SUNXI_MMC_DMA_XFERLEN 0x10000
#define SUNXI_MMC_DMA_FTRGLEVEL 0x20070008
struct sunxi_mmc_softc;
static int sunxi_mmc_match(device_t, cfdata_t, void *);
static void sunxi_mmc_attach(device_t, device_t, void *);
static void sunxi_mmc_attach_i(device_t);
static int sunxi_mmc_intr(void *);
static int sunxi_mmc_idma_setup(struct sunxi_mmc_softc *);
static int sunxi_mmc_host_reset(sdmmc_chipset_handle_t);
static uint32_t sunxi_mmc_host_ocr(sdmmc_chipset_handle_t);
static int sunxi_mmc_host_maxblklen(sdmmc_chipset_handle_t);
static int sunxi_mmc_card_detect(sdmmc_chipset_handle_t);
static int sunxi_mmc_write_protect(sdmmc_chipset_handle_t);
static int sunxi_mmc_bus_power(sdmmc_chipset_handle_t, uint32_t);
static int sunxi_mmc_bus_clock(sdmmc_chipset_handle_t, int);
static int sunxi_mmc_bus_width(sdmmc_chipset_handle_t, int);
static int sunxi_mmc_bus_rod(sdmmc_chipset_handle_t, int);
static void sunxi_mmc_exec_command(sdmmc_chipset_handle_t,
struct sdmmc_command *);
static void sunxi_mmc_card_enable_intr(sdmmc_chipset_handle_t, int);
static void sunxi_mmc_card_intr_ack(sdmmc_chipset_handle_t);
static struct sdmmc_chip_functions sunxi_mmc_chip_functions = {
.host_reset = sunxi_mmc_host_reset,
.host_ocr = sunxi_mmc_host_ocr,
.host_maxblklen = sunxi_mmc_host_maxblklen,
.card_detect = sunxi_mmc_card_detect,
.write_protect = sunxi_mmc_write_protect,
.bus_power = sunxi_mmc_bus_power,
.bus_clock = sunxi_mmc_bus_clock,
.bus_width = sunxi_mmc_bus_width,
.bus_rod = sunxi_mmc_bus_rod,
.exec_command = sunxi_mmc_exec_command,
.card_enable_intr = sunxi_mmc_card_enable_intr,
.card_intr_ack = sunxi_mmc_card_intr_ack,
};
struct sunxi_mmc_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
bus_dma_tag_t sc_dmat;
int sc_phandle;
void *sc_ih;
kmutex_t sc_intr_lock;
kcondvar_t sc_intr_cv;
kcondvar_t sc_idst_cv;
int sc_mmc_width;
int sc_mmc_present;
device_t sc_sdmmc_dev;
uint32_t sc_dma_ftrglevel;
uint32_t sc_idma_xferlen;
bus_dma_segment_t sc_idma_segs[1];
int sc_idma_nsegs;
bus_size_t sc_idma_size;
bus_dmamap_t sc_idma_map;
int sc_idma_ndesc;
void *sc_idma_desc;
uint32_t sc_intr_rint;
uint32_t sc_intr_mint;
uint32_t sc_idma_idst;
struct clk *sc_clk_ahb;
struct clk *sc_clk_mmc;
struct clk *sc_clk_output;
struct clk *sc_clk_sample;
struct fdtbus_reset *sc_rst_ahb;
struct fdtbus_gpio_pin *sc_gpio_cd;
int sc_gpio_cd_inverted;
struct fdtbus_gpio_pin *sc_gpio_wp;
int sc_gpio_wp_inverted;
};
CFATTACH_DECL_NEW(sunxi_mmc, sizeof(struct sunxi_mmc_softc),
sunxi_mmc_match, sunxi_mmc_attach, NULL, NULL);
#define MMC_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
#define MMC_READ(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
static const char * const compatible[] = {
"allwinner,sun7i-a20-mmc",
NULL
};
static int
sunxi_mmc_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
sunxi_mmc_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_mmc_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
char intrstr[128];
bus_addr_t addr;
bus_size_t size;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
sc->sc_clk_ahb = fdtbus_clock_get(phandle, "ahb");
sc->sc_clk_mmc = fdtbus_clock_get(phandle, "mmc");
sc->sc_clk_output = fdtbus_clock_get(phandle, "output");
sc->sc_clk_sample = fdtbus_clock_get(phandle, "sample");
#if notyet
if (sc->sc_clk_ahb == NULL || sc->sc_clk_mmc == NULL ||
sc->sc_clk_output == NULL || sc->sc_clk_sample == NULL) {
#else
if (sc->sc_clk_ahb == NULL || sc->sc_clk_mmc == NULL) {
#endif
aprint_error(": couldn't get clocks\n");
return;
}
sc->sc_rst_ahb = fdtbus_reset_get(phandle, "ahb");
if (sc->sc_rst_ahb == NULL) {
aprint_error(": couldn't get resets\n");
return;
}
if (clk_enable(sc->sc_clk_ahb) != 0 ||
clk_enable(sc->sc_clk_mmc) != 0) {
aprint_error(": couldn't enable clocks\n");
return;
}
if (fdtbus_reset_deassert(sc->sc_rst_ahb) != 0) {
aprint_error(": couldn't de-assert resets\n");
return;
}
sc->sc_dev = self;
sc->sc_phandle = phandle;
sc->sc_bst = faa->faa_bst;
sc->sc_dmat = faa->faa_dmat;
mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO);
cv_init(&sc->sc_intr_cv, "awinmmcirq");
cv_init(&sc->sc_idst_cv, "awinmmcdma");
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
aprint_error(": couldn't map registers\n");
return;
}
aprint_naive("\n");
aprint_normal(": SD/MMC controller\n");
sc->sc_gpio_cd = fdtbus_gpio_acquire(phandle, "cd-gpios",
GPIO_PIN_INPUT);
sc->sc_gpio_wp = fdtbus_gpio_acquire(phandle, "wp-gpios",
GPIO_PIN_INPUT);
sc->sc_gpio_cd_inverted = of_hasprop(phandle, "cd-inverted") ? 0 : 1;
sc->sc_gpio_wp_inverted = of_hasprop(phandle, "wp-inverted") ? 0 : 1;
sc->sc_dma_ftrglevel = SUNXI_MMC_DMA_FTRGLEVEL;
if (sunxi_mmc_idma_setup(sc) != 0) {
aprint_error_dev(self, "failed to setup DMA\n");
return;
}
if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
aprint_error_dev(self, "failed to decode interrupt\n");
return;
}
sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_BIO, FDT_INTR_MPSAFE,
sunxi_mmc_intr, sc);
if (sc->sc_ih == NULL) {
aprint_error_dev(self, "failed to establish interrupt on %s\n",
intrstr);
return;
}
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
config_interrupts(self, sunxi_mmc_attach_i);
}
static int
sunxi_mmc_idma_setup(struct sunxi_mmc_softc *sc)
{
int error;
sc->sc_idma_xferlen = SUNXI_MMC_DMA_XFERLEN;
sc->sc_idma_ndesc = SUNXI_MMC_NDESC;
sc->sc_idma_size = sizeof(struct sunxi_mmc_idma_descriptor) *
sc->sc_idma_ndesc;
error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_idma_size, 0,
sc->sc_idma_size, sc->sc_idma_segs, 1,
&sc->sc_idma_nsegs, BUS_DMA_WAITOK);
if (error)
return error;
error = bus_dmamem_map(sc->sc_dmat, sc->sc_idma_segs,
sc->sc_idma_nsegs, sc->sc_idma_size,
&sc->sc_idma_desc, BUS_DMA_WAITOK);
if (error)
goto free;
error = bus_dmamap_create(sc->sc_dmat, sc->sc_idma_size, 1,
sc->sc_idma_size, 0, BUS_DMA_WAITOK, &sc->sc_idma_map);
if (error)
goto unmap;
error = bus_dmamap_load(sc->sc_dmat, sc->sc_idma_map,
sc->sc_idma_desc, sc->sc_idma_size, NULL, BUS_DMA_WAITOK);
if (error)
goto destroy;
return 0;
destroy:
bus_dmamap_destroy(sc->sc_dmat, sc->sc_idma_map);
unmap:
bus_dmamem_unmap(sc->sc_dmat, sc->sc_idma_desc, sc->sc_idma_size);
free:
bus_dmamem_free(sc->sc_dmat, sc->sc_idma_segs, sc->sc_idma_nsegs);
return error;
}
static int
sunxi_mmc_set_clock(struct sunxi_mmc_softc *sc, u_int freq)
{
return clk_set_rate(sc->sc_clk_mmc, freq * 1000);
}
static void
sunxi_mmc_attach_i(device_t self)
{
struct sunxi_mmc_softc *sc = device_private(self);
struct sdmmcbus_attach_args saa;
uint32_t width;
sunxi_mmc_host_reset(sc);
sunxi_mmc_bus_width(sc, 1);
sunxi_mmc_set_clock(sc, 400);
if (of_getprop_uint32(sc->sc_phandle, "bus-width", &width) != 0)
width = 4;
memset(&saa, 0, sizeof(saa));
saa.saa_busname = "sdmmc";
saa.saa_sct = &sunxi_mmc_chip_functions;
saa.saa_sch = sc;
saa.saa_dmat = sc->sc_dmat;
saa.saa_clkmin = 400;
saa.saa_clkmax = 52000;
saa.saa_caps = SMC_CAPS_DMA |
SMC_CAPS_MULTI_SEG_DMA |
SMC_CAPS_AUTO_STOP |
SMC_CAPS_SD_HIGHSPEED |
SMC_CAPS_MMC_HIGHSPEED;
if (width == 4)
saa.saa_caps |= SMC_CAPS_4BIT_MODE;
if (width == 8)
saa.saa_caps |= SMC_CAPS_8BIT_MODE;
if (sc->sc_gpio_cd)
saa.saa_caps |= SMC_CAPS_POLL_CARD_DET;
sc->sc_sdmmc_dev = config_found(self, &saa, NULL);
}
static int
sunxi_mmc_intr(void *priv)
{
struct sunxi_mmc_softc *sc = priv;
uint32_t idst, rint, mint;
mutex_enter(&sc->sc_intr_lock);
idst = MMC_READ(sc, SUNXI_MMC_IDST);
rint = MMC_READ(sc, SUNXI_MMC_RINT);
mint = MMC_READ(sc, SUNXI_MMC_MINT);
if (!idst && !rint && !mint) {
mutex_exit(&sc->sc_intr_lock);
return 0;
}
MMC_WRITE(sc, SUNXI_MMC_IDST, idst);
MMC_WRITE(sc, SUNXI_MMC_RINT, rint);
MMC_WRITE(sc, SUNXI_MMC_MINT, mint);
#ifdef SUNXI_MMC_DEBUG
device_printf(sc->sc_dev, "mmc intr idst=%08X rint=%08X mint=%08X\n",
idst, rint, mint);
#endif
if (idst) {
sc->sc_idma_idst |= idst;
cv_broadcast(&sc->sc_idst_cv);
}
if (rint) {
sc->sc_intr_rint |= rint;
cv_broadcast(&sc->sc_intr_cv);
}
mutex_exit(&sc->sc_intr_lock);
return 1;
}
static int
sunxi_mmc_wait_rint(struct sunxi_mmc_softc *sc, uint32_t mask, int timeout)
{
int retry;
int error;
KASSERT(mutex_owned(&sc->sc_intr_lock));
if (sc->sc_intr_rint & mask)
return 0;
retry = timeout / hz;
while (retry > 0) {
error = cv_timedwait(&sc->sc_intr_cv,
&sc->sc_intr_lock, hz);
if (error && error != EWOULDBLOCK)
return error;
if (sc->sc_intr_rint & mask)
return 0;
--retry;
}
return ETIMEDOUT;
}
static int
sunxi_mmc_host_reset(sdmmc_chipset_handle_t sch)
{
struct sunxi_mmc_softc *sc = sch;
int retry = 1000;
#ifdef SUNXI_MMC_DEBUG
aprint_normal_dev(sc->sc_dev, "host reset\n");
#endif
MMC_WRITE(sc, SUNXI_MMC_GCTRL,
MMC_READ(sc, SUNXI_MMC_GCTRL) | SUNXI_MMC_GCTRL_RESET);
while (--retry > 0) {
if (!(MMC_READ(sc, SUNXI_MMC_GCTRL) & SUNXI_MMC_GCTRL_RESET))
break;
delay(100);
}
MMC_WRITE(sc, SUNXI_MMC_TIMEOUT, 0xffffffff);
MMC_WRITE(sc, SUNXI_MMC_IMASK,
SUNXI_MMC_INT_CMD_DONE | SUNXI_MMC_INT_ERROR |
SUNXI_MMC_INT_DATA_OVER | SUNXI_MMC_INT_AUTO_CMD_DONE);
MMC_WRITE(sc, SUNXI_MMC_GCTRL,
MMC_READ(sc, SUNXI_MMC_GCTRL) | SUNXI_MMC_GCTRL_INTEN);
return 0;
}
static uint32_t
sunxi_mmc_host_ocr(sdmmc_chipset_handle_t sch)
{
return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V | MMC_OCR_HCS;
}
static int
sunxi_mmc_host_maxblklen(sdmmc_chipset_handle_t sch)
{
return 8192;
}
static int
sunxi_mmc_card_detect(sdmmc_chipset_handle_t sch)
{
struct sunxi_mmc_softc *sc = sch;
if (sc->sc_gpio_cd == NULL) {
return 1; /* no card detect pin, assume present */
} else {
int v = 0, i;
for (i = 0; i < 5; i++) {
v += (fdtbus_gpio_read(sc->sc_gpio_cd) ^
sc->sc_gpio_cd_inverted);
delay(1000);
}
if (v == 5)
sc->sc_mmc_present = 0;
else if (v == 0)
sc->sc_mmc_present = 1;
return sc->sc_mmc_present;
}
}
static int
sunxi_mmc_write_protect(sdmmc_chipset_handle_t sch)
{
struct sunxi_mmc_softc *sc = sch;
if (sc->sc_gpio_wp == NULL) {
return 0; /* no write protect pin, assume rw */
} else {
return fdtbus_gpio_read(sc->sc_gpio_wp) ^
sc->sc_gpio_wp_inverted;
}
}
static int
sunxi_mmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
{
return 0;
}
static int
sunxi_mmc_update_clock(struct sunxi_mmc_softc *sc)
{
uint32_t cmd;
int retry;
#ifdef SUNXI_MMC_DEBUG
aprint_normal_dev(sc->sc_dev, "update clock\n");
#endif
cmd = SUNXI_MMC_CMD_START |
SUNXI_MMC_CMD_UPCLK_ONLY |
SUNXI_MMC_CMD_WAIT_PRE_OVER;
MMC_WRITE(sc, SUNXI_MMC_CMD, cmd);
retry = 0xfffff;
while (--retry > 0) {
if (!(MMC_READ(sc, SUNXI_MMC_CMD) & SUNXI_MMC_CMD_START))
break;
delay(10);
}
if (retry == 0) {
aprint_error_dev(sc->sc_dev, "timeout updating clock\n");
#ifdef SUNXI_MMC_DEBUG
device_printf(sc->sc_dev, "GCTRL: 0x%08x\n",
MMC_READ(sc, SUNXI_MMC_GCTRL));
device_printf(sc->sc_dev, "CLKCR: 0x%08x\n",
MMC_READ(sc, SUNXI_MMC_CLKCR));
device_printf(sc->sc_dev, "TIMEOUT: 0x%08x\n",
MMC_READ(sc, SUNXI_MMC_TIMEOUT));
device_printf(sc->sc_dev, "WIDTH: 0x%08x\n",
MMC_READ(sc, SUNXI_MMC_WIDTH));
device_printf(sc->sc_dev, "CMD: 0x%08x\n",
MMC_READ(sc, SUNXI_MMC_CMD));
device_printf(sc->sc_dev, "MINT: 0x%08x\n",
MMC_READ(sc, SUNXI_MMC_MINT));
device_printf(sc->sc_dev, "RINT: 0x%08x\n",
MMC_READ(sc, SUNXI_MMC_RINT));
device_printf(sc->sc_dev, "STATUS: 0x%08x\n",
MMC_READ(sc, SUNXI_MMC_STATUS));
#endif
return ETIMEDOUT;
}
return 0;
}
static int
sunxi_mmc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
{
struct sunxi_mmc_softc *sc = sch;
uint32_t clkcr;
clkcr = MMC_READ(sc, SUNXI_MMC_CLKCR);
if (clkcr & SUNXI_MMC_CLKCR_CARDCLKON) {
clkcr &= ~SUNXI_MMC_CLKCR_CARDCLKON;
MMC_WRITE(sc, SUNXI_MMC_CLKCR, clkcr);
if (sunxi_mmc_update_clock(sc) != 0)
return 1;
}
if (freq) {
clkcr &= ~SUNXI_MMC_CLKCR_DIV;
MMC_WRITE(sc, SUNXI_MMC_CLKCR, clkcr);
if (sunxi_mmc_update_clock(sc) != 0)
return 1;
if (sunxi_mmc_set_clock(sc, freq) != 0)
return 1;
clkcr |= SUNXI_MMC_CLKCR_CARDCLKON;
MMC_WRITE(sc, SUNXI_MMC_CLKCR, clkcr);
if (sunxi_mmc_update_clock(sc) != 0)
return 1;
}
return 0;
}
static int
sunxi_mmc_bus_width(sdmmc_chipset_handle_t sch, int width)
{
struct sunxi_mmc_softc *sc = sch;
#ifdef SUNXI_MMC_DEBUG
aprint_normal_dev(sc->sc_dev, "width = %d\n", width);
#endif
switch (width) {
case 1:
MMC_WRITE(sc, SUNXI_MMC_WIDTH, SUNXI_MMC_WIDTH_1);
break;
case 4:
MMC_WRITE(sc, SUNXI_MMC_WIDTH, SUNXI_MMC_WIDTH_4);
break;
case 8:
MMC_WRITE(sc, SUNXI_MMC_WIDTH, SUNXI_MMC_WIDTH_8);
break;
default:
return 1;
}
sc->sc_mmc_width = width;
return 0;
}
static int
sunxi_mmc_bus_rod(sdmmc_chipset_handle_t sch, int on)
{
return -1;
}
static int
sunxi_mmc_dma_prepare(struct sunxi_mmc_softc *sc, struct sdmmc_command *cmd)
{
struct sunxi_mmc_idma_descriptor *dma = sc->sc_idma_desc;
bus_addr_t desc_paddr = sc->sc_idma_map->dm_segs[0].ds_addr;
bus_size_t off;
int desc, resid, seg;
uint32_t val;
desc = 0;
for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
bus_addr_t paddr = cmd->c_dmamap->dm_segs[seg].ds_addr;
bus_size_t len = cmd->c_dmamap->dm_segs[seg].ds_len;
resid = min(len, cmd->c_resid);
off = 0;
while (resid > 0) {
if (desc == sc->sc_idma_ndesc)
break;
len = min(sc->sc_idma_xferlen, resid);
dma[desc].dma_buf_size = htole32(len);
dma[desc].dma_buf_addr = htole32(paddr + off);
dma[desc].dma_config = htole32(SUNXI_MMC_IDMA_CONFIG_CH |
SUNXI_MMC_IDMA_CONFIG_OWN);
cmd->c_resid -= len;
resid -= len;
off += len;
if (desc == 0) {
dma[desc].dma_config |= htole32(SUNXI_MMC_IDMA_CONFIG_FD);
}
if (cmd->c_resid == 0) {
dma[desc].dma_config |= htole32(SUNXI_MMC_IDMA_CONFIG_LD);
dma[desc].dma_config |= htole32(SUNXI_MMC_IDMA_CONFIG_ER);
dma[desc].dma_next = 0;
} else {
dma[desc].dma_config |=
htole32(SUNXI_MMC_IDMA_CONFIG_DIC);
dma[desc].dma_next = htole32(
desc_paddr + ((desc+1) *
sizeof(struct sunxi_mmc_idma_descriptor)));
}
++desc;
}
}
if (desc == sc->sc_idma_ndesc) {
aprint_error_dev(sc->sc_dev,
"not enough descriptors for %d byte transfer!\n",
cmd->c_datalen);
return EIO;
}
bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0,
sc->sc_idma_size, BUS_DMASYNC_PREWRITE);
sc->sc_idma_idst = 0;
val = MMC_READ(sc, SUNXI_MMC_GCTRL);
val |= SUNXI_MMC_GCTRL_DMAEN;
val |= SUNXI_MMC_GCTRL_INTEN;
MMC_WRITE(sc, SUNXI_MMC_GCTRL, val);
val |= SUNXI_MMC_GCTRL_DMARESET;
MMC_WRITE(sc, SUNXI_MMC_GCTRL, val);
MMC_WRITE(sc, SUNXI_MMC_DMAC, SUNXI_MMC_DMAC_SOFTRESET);
MMC_WRITE(sc, SUNXI_MMC_DMAC,
SUNXI_MMC_DMAC_IDMA_ON|SUNXI_MMC_DMAC_FIX_BURST);
val = MMC_READ(sc, SUNXI_MMC_IDIE);
val &= ~(SUNXI_MMC_IDST_RECEIVE_INT|SUNXI_MMC_IDST_TRANSMIT_INT);
if (cmd->c_flags & SCF_CMD_READ)
val |= SUNXI_MMC_IDST_RECEIVE_INT;
else
val |= SUNXI_MMC_IDST_TRANSMIT_INT;
MMC_WRITE(sc, SUNXI_MMC_IDIE, val);
MMC_WRITE(sc, SUNXI_MMC_DLBA, desc_paddr);
MMC_WRITE(sc, SUNXI_MMC_FTRGLEVEL, sc->sc_dma_ftrglevel);
return 0;
}
static void
sunxi_mmc_dma_complete(struct sunxi_mmc_softc *sc)
{
bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0,
sc->sc_idma_size, BUS_DMASYNC_POSTWRITE);
}
static void
sunxi_mmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
{
struct sunxi_mmc_softc *sc = sch;
uint32_t cmdval = SUNXI_MMC_CMD_START;
int retry;
#ifdef SUNXI_MMC_DEBUG
aprint_normal_dev(sc->sc_dev,
"opcode %d flags 0x%x data %p datalen %d blklen %d\n",
cmd->c_opcode, cmd->c_flags, cmd->c_data, cmd->c_datalen,
cmd->c_blklen);
#endif
mutex_enter(&sc->sc_intr_lock);
if (cmd->c_opcode == 0)
cmdval |= SUNXI_MMC_CMD_SEND_INIT_SEQ;
if (cmd->c_flags & SCF_RSP_PRESENT)
cmdval |= SUNXI_MMC_CMD_RSP_EXP;
if (cmd->c_flags & SCF_RSP_136)
cmdval |= SUNXI_MMC_CMD_LONG_RSP;
if (cmd->c_flags & SCF_RSP_CRC)
cmdval |= SUNXI_MMC_CMD_CHECK_RSP_CRC;
if (cmd->c_datalen > 0) {
unsigned int nblks;
cmdval |= SUNXI_MMC_CMD_DATA_EXP | SUNXI_MMC_CMD_WAIT_PRE_OVER;
if (!ISSET(cmd->c_flags, SCF_CMD_READ)) {
cmdval |= SUNXI_MMC_CMD_WRITE;
}
nblks = cmd->c_datalen / cmd->c_blklen;
if (nblks == 0 || (cmd->c_datalen % cmd->c_blklen) != 0)
++nblks;
if (nblks > 1) {
cmdval |= SUNXI_MMC_CMD_SEND_AUTO_STOP;
}
MMC_WRITE(sc, SUNXI_MMC_BLKSZ, cmd->c_blklen);
MMC_WRITE(sc, SUNXI_MMC_BYTECNT, nblks * cmd->c_blklen);
}
sc->sc_intr_rint = 0;
MMC_WRITE(sc, SUNXI_MMC_A12A,
(cmdval & SUNXI_MMC_CMD_SEND_AUTO_STOP) ? 0 : 0xffff);
MMC_WRITE(sc, SUNXI_MMC_ARG, cmd->c_arg);
#ifdef SUNXI_MMC_DEBUG
aprint_normal_dev(sc->sc_dev, "cmdval = %08x\n", cmdval);
#endif
if (cmd->c_datalen == 0) {
MMC_WRITE(sc, SUNXI_MMC_CMD, cmdval | cmd->c_opcode);
} else {
cmd->c_resid = cmd->c_datalen;
cmd->c_error = sunxi_mmc_dma_prepare(sc, cmd);
MMC_WRITE(sc, SUNXI_MMC_CMD, cmdval | cmd->c_opcode);
if (cmd->c_error == 0) {
const uint32_t idst_mask =
SUNXI_MMC_IDST_ERROR | SUNXI_MMC_IDST_COMPLETE;
retry = 10;
while ((sc->sc_idma_idst & idst_mask) == 0) {
if (retry-- == 0) {
cmd->c_error = ETIMEDOUT;
break;
}
cv_timedwait(&sc->sc_idst_cv,
&sc->sc_intr_lock, hz);
}
}
sunxi_mmc_dma_complete(sc);
if (sc->sc_idma_idst & SUNXI_MMC_IDST_ERROR) {
cmd->c_error = EIO;
} else if (!(sc->sc_idma_idst & SUNXI_MMC_IDST_COMPLETE)) {
cmd->c_error = ETIMEDOUT;
}
if (cmd->c_error) {
#ifdef SUNXI_MMC_DEBUG
aprint_error_dev(sc->sc_dev,
"xfer failed, error %d\n", cmd->c_error);
#endif
goto done;
}
}
cmd->c_error = sunxi_mmc_wait_rint(sc,
SUNXI_MMC_INT_ERROR|SUNXI_MMC_INT_CMD_DONE, hz * 10);
if (cmd->c_error == 0 && (sc->sc_intr_rint & SUNXI_MMC_INT_ERROR)) {
if (sc->sc_intr_rint & SUNXI_MMC_INT_RESP_TIMEOUT) {
cmd->c_error = ETIMEDOUT;
} else {
cmd->c_error = EIO;
}
}
if (cmd->c_error) {
#ifdef SUNXI_MMC_DEBUG
aprint_error_dev(sc->sc_dev,
"cmd failed, error %d\n", cmd->c_error);
#endif
goto done;
}
if (cmd->c_datalen > 0) {
cmd->c_error = sunxi_mmc_wait_rint(sc,
SUNXI_MMC_INT_ERROR|
SUNXI_MMC_INT_AUTO_CMD_DONE|
SUNXI_MMC_INT_DATA_OVER,
hz*10);
if (cmd->c_error == 0 &&
(sc->sc_intr_rint & SUNXI_MMC_INT_ERROR)) {
cmd->c_error = ETIMEDOUT;
}
if (cmd->c_error) {
#ifdef SUNXI_MMC_DEBUG
aprint_error_dev(sc->sc_dev,
"data timeout, rint = %08x\n",
sc->sc_intr_rint);
#endif
cmd->c_error = ETIMEDOUT;
goto done;
}
}
if (cmd->c_flags & SCF_RSP_PRESENT) {
if (cmd->c_flags & SCF_RSP_136) {
cmd->c_resp[0] = MMC_READ(sc, SUNXI_MMC_RESP0);
cmd->c_resp[1] = MMC_READ(sc, SUNXI_MMC_RESP1);
cmd->c_resp[2] = MMC_READ(sc, SUNXI_MMC_RESP2);
cmd->c_resp[3] = MMC_READ(sc, SUNXI_MMC_RESP3);
if (cmd->c_flags & SCF_RSP_CRC) {
cmd->c_resp[0] = (cmd->c_resp[0] >> 8) |
(cmd->c_resp[1] << 24);
cmd->c_resp[1] = (cmd->c_resp[1] >> 8) |
(cmd->c_resp[2] << 24);
cmd->c_resp[2] = (cmd->c_resp[2] >> 8) |
(cmd->c_resp[3] << 24);
cmd->c_resp[3] = (cmd->c_resp[3] >> 8);
}
} else {
cmd->c_resp[0] = MMC_READ(sc, SUNXI_MMC_RESP0);
}
}
done:
cmd->c_flags |= SCF_ITSDONE;
mutex_exit(&sc->sc_intr_lock);
if (cmd->c_error) {
#ifdef SUNXI_MMC_DEBUG
aprint_error_dev(sc->sc_dev, "i/o error %d\n", cmd->c_error);
#endif
MMC_WRITE(sc, SUNXI_MMC_GCTRL,
MMC_READ(sc, SUNXI_MMC_GCTRL) |
SUNXI_MMC_GCTRL_DMARESET | SUNXI_MMC_GCTRL_FIFORESET);
for (retry = 0; retry < 1000; retry++) {
if (!(MMC_READ(sc, SUNXI_MMC_GCTRL) & SUNXI_MMC_GCTRL_RESET))
break;
delay(10);
}
sunxi_mmc_update_clock(sc);
}
MMC_WRITE(sc, SUNXI_MMC_GCTRL,
MMC_READ(sc, SUNXI_MMC_GCTRL) | SUNXI_MMC_GCTRL_FIFORESET);
}
static void
sunxi_mmc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable)
{
}
static void
sunxi_mmc_card_intr_ack(sdmmc_chipset_handle_t sch)
{
}

View File

@ -0,0 +1,179 @@
/* $NetBSD: sunxi_mmc.h,v 1.2.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#ifndef _ARM_SUNXI_MMC_H
#define _ARM_SUNXI_MMC_H
#define SUNXI_MMC_GCTRL 0x0000
#define SUNXI_MMC_CLKCR 0x0004
#define SUNXI_MMC_TIMEOUT 0x0008
#define SUNXI_MMC_WIDTH 0x000C
#define SUNXI_MMC_BLKSZ 0x0010
#define SUNXI_MMC_BYTECNT 0x0014
#define SUNXI_MMC_CMD 0x0018
#define SUNXI_MMC_ARG 0x001C
#define SUNXI_MMC_RESP0 0x0020
#define SUNXI_MMC_RESP1 0x0024
#define SUNXI_MMC_RESP2 0x0028
#define SUNXI_MMC_RESP3 0x002C
#define SUNXI_MMC_IMASK 0x0030
#define SUNXI_MMC_MINT 0x0034
#define SUNXI_MMC_RINT 0x0038
#define SUNXI_MMC_STATUS 0x003C
#define SUNXI_MMC_FTRGLEVEL 0x0040
#define SUNXI_MMC_FUNCSEL 0x0044
#define SUNXI_MMC_CBCR 0x0048
#define SUNXI_MMC_BBCR 0x004C
#define SUNXI_MMC_DBGC 0x0050
#define SUNXI_MMC_A12A 0x0058 /* A80 */
#define SUNXI_MMC_HWRST 0x0078 /* A80 */
#define SUNXI_MMC_DMAC 0x0080
#define SUNXI_MMC_DLBA 0x0084
#define SUNXI_MMC_IDST 0x0088
#define SUNXI_MMC_IDIE 0x008C
#define SUNXI_MMC_CHDA 0x0090
#define SUNXI_MMC_CBDA 0x0094
#define SUNXI_MMC_FIFO 0x0100
#define SUNXI_MMC_GCTRL_ACCESS_BY_AHB __BIT(31)
#define SUNXI_MMC_GCTRL_WAIT_MEM_ACCESS_DONE __BIT(30)
#define SUNXI_MMC_GCTRL_DDR_MODE __BIT(10)
#define SUNXI_MMC_GCTRL_DEBOUNCEEN __BIT(8)
#define SUNXI_MMC_GCTRL_DMAEN __BIT(5)
#define SUNXI_MMC_GCTRL_INTEN __BIT(4)
#define SUNXI_MMC_GCTRL_DMARESET __BIT(2)
#define SUNXI_MMC_GCTRL_FIFORESET __BIT(1)
#define SUNXI_MMC_GCTRL_SOFTRESET __BIT(0)
#define SUNXI_MMC_GCTRL_RESET \
(SUNXI_MMC_GCTRL_SOFTRESET | SUNXI_MMC_GCTRL_FIFORESET | \
SUNXI_MMC_GCTRL_DMARESET)
#define SUNXI_MMC_CLKCR_LOWPOWERON __BIT(17)
#define SUNXI_MMC_CLKCR_CARDCLKON __BIT(16)
#define SUNXI_MMC_CLKCR_DIV __BITS(15,0)
#define SUNXI_MMC_WIDTH_1 0
#define SUNXI_MMC_WIDTH_4 1
#define SUNXI_MMC_WIDTH_8 2
#define SUNXI_MMC_CMD_START __BIT(31)
#define SUNXI_MMC_CMD_USE_HOLD_REG __BIT(29)
#define SUNXI_MMC_CMD_VOL_SWITCH __BIT(28)
#define SUNXI_MMC_CMD_BOOT_ABORT __BIT(27)
#define SUNXI_MMC_CMD_BOOT_ACK_EXP __BIT(26)
#define SUNXI_MMC_CMD_ALT_BOOT_OPT __BIT(25)
#define SUNXI_MMC_CMD_ENBOOT __BIT(24)
#define SUNXI_MMC_CMD_CCS_EXP __BIT(23)
#define SUNXI_MMC_CMD_RD_CEATA_DEV __BIT(22)
#define SUNXI_MMC_CMD_UPCLK_ONLY __BIT(21)
#define SUNXI_MMC_CMD_SEND_INIT_SEQ __BIT(15)
#define SUNXI_MMC_CMD_STOP_ABORT_CMD __BIT(14)
#define SUNXI_MMC_CMD_WAIT_PRE_OVER __BIT(13)
#define SUNXI_MMC_CMD_SEND_AUTO_STOP __BIT(12)
#define SUNXI_MMC_CMD_SEQMOD __BIT(11)
#define SUNXI_MMC_CMD_WRITE __BIT(10)
#define SUNXI_MMC_CMD_DATA_EXP __BIT(9)
#define SUNXI_MMC_CMD_CHECK_RSP_CRC __BIT(8)
#define SUNXI_MMC_CMD_LONG_RSP __BIT(7)
#define SUNXI_MMC_CMD_RSP_EXP __BIT(6)
#define SUNXI_MMC_INT_CARD_REMOVE __BIT(31)
#define SUNXI_MMC_INT_CARD_INSERT __BIT(30)
#define SUNXI_MMC_INT_SDIO_INT __BIT(16)
#define SUNXI_MMC_INT_END_BIT_ERR __BIT(15)
#define SUNXI_MMC_INT_AUTO_CMD_DONE __BIT(14)
#define SUNXI_MMC_INT_START_BIT_ERR __BIT(13)
#define SUNXI_MMC_INT_HW_LOCKED __BIT(12)
#define SUNXI_MMC_INT_FIFO_RUN_ERR __BIT(11)
#define SUNXI_MMC_INT_VOL_CHG_DONE __BIT(10)
#define SUNXI_MMC_INT_DATA_STARVE __BIT(10)
#define SUNXI_MMC_INT_BOOT_START __BIT(9)
#define SUNXI_MMC_INT_DATA_TIMEOUT __BIT(9)
#define SUNXI_MMC_INT_ACK_RCV __BIT(8)
#define SUNXI_MMC_INT_RESP_TIMEOUT __BIT(8)
#define SUNXI_MMC_INT_DATA_CRC_ERR __BIT(7)
#define SUNXI_MMC_INT_RESP_CRC_ERR __BIT(6)
#define SUNXI_MMC_INT_RX_DATA_REQ __BIT(5)
#define SUNXI_MMC_INT_TX_DATA_REQ __BIT(4)
#define SUNXI_MMC_INT_DATA_OVER __BIT(3)
#define SUNXI_MMC_INT_CMD_DONE __BIT(2)
#define SUNXI_MMC_INT_RESP_ERR __BIT(1)
#define SUNXI_MMC_INT_ERROR \
(SUNXI_MMC_INT_RESP_ERR | SUNXI_MMC_INT_RESP_CRC_ERR | \
SUNXI_MMC_INT_DATA_CRC_ERR | SUNXI_MMC_INT_RESP_TIMEOUT | \
SUNXI_MMC_INT_FIFO_RUN_ERR | SUNXI_MMC_INT_HW_LOCKED | \
SUNXI_MMC_INT_START_BIT_ERR | SUNXI_MMC_INT_END_BIT_ERR)
#define SUNXI_MMC_STATUS_DMAREQ __BIT(31)
#define SUNXI_MMC_STATUS_DATA_FSM_BUSY __BIT(10)
#define SUNXI_MMC_STATUS_CARD_DATA_BUSY __BIT(9)
#define SUNXI_MMC_STATUS_CARD_PRESENT __BIT(8)
#define SUNXI_MMC_STATUS_FIFO_FULL __BIT(3)
#define SUNXI_MMC_STATUS_FIFO_EMPTY __BIT(2)
#define SUNXI_MMC_STATUS_TXWL_FLAG __BIT(1)
#define SUNXI_MMC_STATUS_RXWL_FLAG __BIT(0)
#define SUNXI_MMC_FUNCSEL_CEATA_DEV_INTEN __BIT(10)
#define SUNXI_MMC_FUNCSEL_SEND_AUTO_STOP_CCSD __BIT(9)
#define SUNXI_MMC_FUNCSEL_SEND_CCSD __BIT(8)
#define SUNXI_MMC_FUNCSEL_ABT_RD_DATA __BIT(2)
#define SUNXI_MMC_FUNCSEL_SDIO_RD_WAIT __BIT(1)
#define SUNXI_MMC_FUNCSEL_SEND_IRQ_RSP __BIT(0)
#define SUNXI_MMC_DMAC_REFETCH_DES __BIT(31)
#define SUNXI_MMC_DMAC_IDMA_ON __BIT(7)
#define SUNXI_MMC_DMAC_FIX_BURST __BIT(1)
#define SUNXI_MMC_DMAC_SOFTRESET __BIT(0)
#define SUNXI_MMC_IDST_HOST_ABT __BIT(10)
#define SUNXI_MMC_IDST_ABNORMAL_INT_SUM __BIT(9)
#define SUNXI_MMC_IDST_NORMAL_INT_SUM __BIT(8)
#define SUNXI_MMC_IDST_CARD_ERR_SUM __BIT(5)
#define SUNXI_MMC_IDST_DES_INVALID __BIT(4)
#define SUNXI_MMC_IDST_FATAL_BUS_ERR __BIT(2)
#define SUNXI_MMC_IDST_RECEIVE_INT __BIT(1)
#define SUNXI_MMC_IDST_TRANSMIT_INT __BIT(0)
#define SUNXI_MMC_IDST_ERROR \
(SUNXI_MMC_IDST_ABNORMAL_INT_SUM | SUNXI_MMC_IDST_CARD_ERR_SUM | \
SUNXI_MMC_IDST_DES_INVALID | SUNXI_MMC_IDST_FATAL_BUS_ERR)
#define SUNXI_MMC_IDST_COMPLETE \
(SUNXI_MMC_IDST_RECEIVE_INT | SUNXI_MMC_IDST_TRANSMIT_INT)
#define SUNXI_MMC_IDMA_CONFIG_DIC __BIT(1)
#define SUNXI_MMC_IDMA_CONFIG_LD __BIT(2)
#define SUNXI_MMC_IDMA_CONFIG_FD __BIT(3)
#define SUNXI_MMC_IDMA_CONFIG_CH __BIT(4)
#define SUNXI_MMC_IDMA_CONFIG_ER __BIT(5)
#define SUNXI_MMC_IDMA_CONFIG_CES __BIT(30)
#define SUNXI_MMC_IDMA_CONFIG_OWN __BIT(31)
struct sunxi_mmc_idma_descriptor {
uint32_t dma_config;
#define SUNXI_MMC_IDMA_CONFIG_DIC __BIT(1)
#define SUNXI_MMC_IDMA_CONFIG_LD __BIT(2)
#define SUNXI_MMC_IDMA_CONFIG_FD __BIT(3)
#define SUNXI_MMC_IDMA_CONFIG_CH __BIT(4)
#define SUNXI_MMC_IDMA_CONFIG_ER __BIT(5)
#define SUNXI_MMC_IDMA_CONFIG_CES __BIT(30)
#define SUNXI_MMC_IDMA_CONFIG_OWN __BIT(31)
uint32_t dma_buf_size;
uint32_t dma_buf_addr;
uint32_t dma_next;
} __packed;
#endif /* _ARM_SUNXI_MMC_H */

View File

@ -0,0 +1,170 @@
/* $NetBSD: sunxi_platform.c,v 1.5.4.2 2017/07/18 19:13:08 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include "opt_soc.h"
#include "opt_multiprocessor.h"
#include "opt_fdt_arm.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.5.4.2 2017/07/18 19:13:08 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <sys/termios.h>
#include <dev/fdt/fdtvar.h>
#include <arm/fdt/arm_fdtvar.h>
#include <uvm/uvm_extern.h>
#include <machine/bootconfig.h>
#include <arm/cpufunc.h>
#include <arm/cortex/gtmr_var.h>
#include <arm/cortex/gic_reg.h>
#include <dev/ic/ns16550reg.h>
#include <dev/ic/comreg.h>
#include <arm/arm/psci.h>
#include <arm/fdt/psci_fdt.h>
#include <arm/sunxi/sunxi_platform.h>
#define SUNXI_REF_FREQ 24000000
#define SUN6I_WDT_BASE 0x01c20ca0
#define SUN6I_WDT_SIZE 0x20
#define SUN6I_WDT_CFG 0x14
#define SUN6I_WDT_CFG_SYS 1
#define SUN6I_WDT_MODE 0x18
#define SUN6I_WDT_MODE_EN 1
#define DEVMAP_ALIGN(a) ((a) & ~L1_S_OFFSET)
#define DEVMAP_SIZE(s) roundup2((s), L1_S_SIZE)
#define DEVMAP_ENTRY(va, pa, sz) \
{ \
.pd_va = DEVMAP_ALIGN(va), \
.pd_pa = DEVMAP_ALIGN(pa), \
.pd_size = DEVMAP_SIZE(sz), \
.pd_prot = VM_PROT_READ|VM_PROT_WRITE, \
.pd_cache = PTE_NOCACHE \
}
#define DEVMAP_ENTRY_END { 0 }
extern struct bus_space armv7_generic_bs_tag;
extern struct bus_space armv7_generic_a4x_bs_tag;
extern struct arm32_bus_dma_tag armv7_generic_dma_tag;
static const struct pmap_devmap *
sunxi_platform_devmap(void)
{
static const struct pmap_devmap devmap[] = {
DEVMAP_ENTRY(SUNXI_CORE_VBASE,
SUNXI_CORE_PBASE,
SUNXI_CORE_SIZE),
DEVMAP_ENTRY_END
};
return devmap;
}
static void
sunxi_platform_init_attach_args(struct fdt_attach_args *faa)
{
faa->faa_bst = &armv7_generic_bs_tag;
faa->faa_a4x_bst = &armv7_generic_a4x_bs_tag;
faa->faa_dmat = &armv7_generic_dma_tag;
}
static void
sunxi_platform_early_putchar(char c)
{
#ifdef CONSADDR
#define CONSADDR_VA ((CONSADDR - SUNXI_CORE_PBASE) + SUNXI_CORE_VBASE)
volatile uint32_t *uartaddr = (volatile uint32_t *)CONSADDR_VA;
while ((uartaddr[com_lsr] & LSR_TXRDY) == 0)
;
uartaddr[com_data] = c;
#endif
}
static void
sunxi_platform_device_register(device_t self, void *aux)
{
}
static u_int
sunxi_platform_uart_freq(void)
{
return SUNXI_REF_FREQ;
}
static void
sun6i_platform_reset(void)
{
bus_space_tag_t bst = &armv7_generic_bs_tag;
bus_space_handle_t bsh;
bus_space_map(bst, SUN6I_WDT_BASE, SUN6I_WDT_SIZE, 0, &bsh);
bus_space_write_4(bst, bsh, SUN6I_WDT_CFG, SUN6I_WDT_CFG_SYS);
bus_space_write_4(bst, bsh, SUN6I_WDT_MODE, SUN6I_WDT_MODE_EN);
}
static const struct arm_platform sun8i_platform = {
.devmap = sunxi_platform_devmap,
.bootstrap = psci_fdt_bootstrap,
.init_attach_args = sunxi_platform_init_attach_args,
.early_putchar = sunxi_platform_early_putchar,
.device_register = sunxi_platform_device_register,
.reset = sun6i_platform_reset,
.delay = gtmr_delay,
.uart_freq = sunxi_platform_uart_freq,
};
ARM_PLATFORM(sun8i_h3, "allwinner,sun8i-h3", &sun8i_platform);
ARM_PLATFORM(sun8i_a83t, "allwinner,sun8i-a83t", &sun8i_platform);
static const struct arm_platform sun6i_platform = {
.devmap = sunxi_platform_devmap,
.bootstrap = psci_fdt_bootstrap,
.init_attach_args = sunxi_platform_init_attach_args,
.early_putchar = sunxi_platform_early_putchar,
.device_register = sunxi_platform_device_register,
.reset = sun6i_platform_reset,
.delay = gtmr_delay,
.uart_freq = sunxi_platform_uart_freq,
};
ARM_PLATFORM(sun6i_a31, "allwinner,sun6i-a31", &sun6i_platform);

View File

@ -0,0 +1,38 @@
/* $NetBSD: sunxi_platform.h,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#ifndef _ARM_SUNXI_PLATFORM_H
#define _ARM_SUNXI_PLATFORM_H
#include <arch/evbarm/fdt/platform.h>
#define SUNXI_CORE_VBASE (KERNEL_VM_BASE + KERNEL_VM_SIZE)
#define SUNXI_CORE_PBASE 0x01c00000
#define SUNXI_CORE_SIZE 0x00400000
#endif /* _ARM_SUNXI_PLATFORM_H */

View File

@ -0,0 +1,149 @@
/* $NetBSD: sunxi_resets.c,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_resets.c,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <dev/fdt/fdtvar.h>
#include <dev/clk/clk_backend.h>
#define RESET_REG(index) (((index) / 32) * 4)
#define RESET_MASK(index) __BIT((index) % 32)
static const char * compatible[] = {
"allwinner,sun6i-a31-clock-reset",
NULL
};
struct sunxi_resets_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
};
#define RESET_READ(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define RESET_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
static void *
sunxi_resets_acquire(device_t dev, const void *data, size_t len)
{
if (len != 4)
return NULL;
/* Specifier is an index. Just return it. */
return (void *)(uintptr_t)be32dec(data);
}
static void
sunxi_resets_release(device_t dev, void *priv)
{
}
static int
sunxi_resets_assert(device_t dev, void *priv)
{
struct sunxi_resets_softc * const sc = device_private(dev);
const uintptr_t index = (uintptr_t)priv;
const bus_size_t reset_reg = RESET_REG(index);
const uint32_t reset_mask = RESET_MASK(index);
const uint32_t val = RESET_READ(sc, reset_reg);
RESET_WRITE(sc, reset_reg, val & ~reset_mask);
return 0;
}
static int
sunxi_resets_deassert(device_t dev, void *priv)
{
struct sunxi_resets_softc * const sc = device_private(dev);
const uintptr_t index = (uintptr_t)priv;
const bus_size_t reset_reg = RESET_REG(index);
const uint32_t reset_mask = RESET_MASK(index);
const uint32_t val = RESET_READ(sc, reset_reg);
RESET_WRITE(sc, reset_reg, val | reset_mask);
return 0;
}
static const struct fdtbus_reset_controller_func sunxi_fdtreset_funcs = {
.acquire = sunxi_resets_acquire,
.release = sunxi_resets_release,
.reset_assert = sunxi_resets_assert,
.reset_deassert = sunxi_resets_deassert,
};
static int
sunxi_resets_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
sunxi_resets_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_resets_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
bus_addr_t addr;
bus_size_t size;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
sc->sc_dev = self;
sc->sc_bst = faa->faa_bst;
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
aprint_error(": couldn't map registers\n");
return;
}
aprint_naive("\n");
aprint_normal("\n");
fdtbus_register_reset_controller(sc->sc_dev, phandle,
&sunxi_fdtreset_funcs);
}
CFATTACH_DECL_NEW(sunxi_resets, sizeof(struct sunxi_resets_softc),
sunxi_resets_match, sunxi_resets_attach, NULL, NULL);

View File

@ -0,0 +1,479 @@
/* $NetBSD: sunxi_rsb.c,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2014-2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_rsb.c,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <dev/i2c/i2cvar.h>
#include <dev/fdt/fdtvar.h>
#include <arm/sunxi/sunxi_rsb.h>
enum sunxi_rsb_type {
SUNXI_P2WI,
SUNXI_RSB,
};
static const struct of_compat_data compat_data[] = {
{ "allwinner,sun6i-a31-p2wi", SUNXI_P2WI },
{ "allwinner,sun8i-a23-rsb", SUNXI_RSB },
{ NULL }
};
#define RSB_ADDR_PMIC_PRIMARY 0x3a3
#define RSB_ADDR_PMIC_SECONDARY 0x745
#define RSB_ADDR_PERIPH_IC 0xe89
/*
* Device address to Run-time address mappings.
*
* Run-time address (RTA) is an 8-bit value used to address the device during
* a read or write transaction. The following are valid RTAs:
* 0x17 0x2d 0x3a 0x4e 0x59 0x63 0x74 0x8b 0x9c 0xa6 0xb1 0xc5 0xd2 0xe8 0xff
*
* Allwinner uses RTA 0x2d for the primary PMIC, 0x3a for the secondary PMIC,
* and 0x4e for the peripheral IC (where applicable).
*/
static const struct {
uint16_t addr;
uint8_t rta;
} rsb_rtamap[] = {
{ .addr = RSB_ADDR_PMIC_PRIMARY, .rta = 0x2d },
{ .addr = RSB_ADDR_PMIC_SECONDARY, .rta = 0x3a },
{ .addr = RSB_ADDR_PERIPH_IC, .rta = 0x4e },
{ .addr = 0, .rta = 0 }
};
struct sunxi_rsb_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
enum sunxi_rsb_type sc_type;
struct i2c_controller sc_ic;
kmutex_t sc_lock;
kcondvar_t sc_cv;
device_t sc_i2cdev;
void *sc_ih;
uint32_t sc_stat;
uint16_t sc_rsb_last_da;
};
#define RSB_READ(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define RSB_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
static int sunxi_rsb_acquire_bus(void *, int);
static void sunxi_rsb_release_bus(void *, int);
static int sunxi_rsb_exec(void *, i2c_op_t, i2c_addr_t, const void *,
size_t, void *, size_t, int);
static int sunxi_rsb_intr(void *);
static int sunxi_rsb_wait(struct sunxi_rsb_softc *, int);
static int sunxi_rsb_rsb_config(struct sunxi_rsb_softc *,
uint8_t, i2c_addr_t, int);
static int sunxi_rsb_match(device_t, cfdata_t, void *);
static void sunxi_rsb_attach(device_t, device_t, void *);
static i2c_tag_t
sunxi_rsb_get_tag(device_t dev)
{
struct sunxi_rsb_softc * const sc = device_private(dev);
return &sc->sc_ic;
}
static const struct fdtbus_i2c_controller_func sunxi_rsb_funcs = {
.get_tag = sunxi_rsb_get_tag,
};
CFATTACH_DECL_NEW(sunxi_rsb, sizeof(struct sunxi_rsb_softc),
sunxi_rsb_match, sunxi_rsb_attach, NULL, NULL);
static int
sunxi_rsb_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compat_data(faa->faa_phandle, compat_data);
}
static void
sunxi_rsb_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_rsb_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
struct i2cbus_attach_args iba;
prop_dictionary_t devs;
uint32_t address_cells;
struct fdtbus_reset *rst;
struct clk *clk;
char intrstr[128];
bus_addr_t addr;
bus_size_t size;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
aprint_error(": couldn't decode interrupt\n");
return;
}
if ((clk = fdtbus_clock_get_index(phandle, 0)) != NULL)
if (clk_enable(clk) != 0) {
aprint_error(": couldn't enable clock\n");
return;
}
if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL)
if (fdtbus_reset_deassert(rst) != 0) {
aprint_error(": couldn't de-assert reset\n");
return;
}
sc->sc_dev = self;
sc->sc_type = of_search_compatible(phandle, compat_data)->data;
sc->sc_bst = faa->faa_bst;
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
aprint_error(": couldn't map registers\n");
return;
}
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SCHED);
cv_init(&sc->sc_cv, "awinp2wi");
aprint_naive("\n");
aprint_normal(": %s\n", sc->sc_type == SUNXI_P2WI ? "P2WI" : "RSB");
sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, 0,
sunxi_rsb_intr, sc);
if (sc->sc_ih == NULL) {
aprint_error_dev(self, "couldn't establish interrupt on %s\n",
intrstr);
return;
}
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
/* Enable interrupts */
RSB_WRITE(sc, RSB_INTE_REG,
RSB_INTE_LOAD_BSY_ENB |
RSB_INTE_TRANS_ERR_ENB |
RSB_INTE_TRANS_OVER_ENB);
RSB_WRITE(sc, RSB_CTRL_REG,
RSB_CTRL_GLOBAL_INT_ENB);
sc->sc_ic.ic_cookie = sc;
sc->sc_ic.ic_acquire_bus = sunxi_rsb_acquire_bus;
sc->sc_ic.ic_release_bus = sunxi_rsb_release_bus;
sc->sc_ic.ic_exec = sunxi_rsb_exec;
fdtbus_register_i2c_controller(self, phandle, &sunxi_rsb_funcs);
devs = prop_dictionary_create();
if (of_getprop_uint32(phandle, "#address-cells", &address_cells))
address_cells = 1;
of_enter_i2c_devs(devs, phandle, address_cells * 4, 0);
memset(&iba, 0, sizeof(iba));
iba.iba_tag = &sc->sc_ic;
iba.iba_child_devices = prop_dictionary_get(devs, "i2c-child-devices");
if (iba.iba_child_devices)
prop_object_retain(iba.iba_child_devices);
else
iba.iba_child_devices = prop_array_create();
prop_object_release(devs);
sc->sc_i2cdev = config_found_ia(self, "i2cbus", &iba, iicbus_print);
}
static int
sunxi_rsb_intr(void *priv)
{
struct sunxi_rsb_softc *sc = priv;
uint32_t stat;
stat = RSB_READ(sc, RSB_STAT_REG);
if ((stat & RSB_STAT_MASK) == 0)
return 0;
RSB_WRITE(sc, RSB_STAT_REG, stat & RSB_STAT_MASK);
mutex_enter(&sc->sc_lock);
sc->sc_stat |= stat;
cv_broadcast(&sc->sc_cv);
mutex_exit(&sc->sc_lock);
return 1;
}
static int
sunxi_rsb_wait(struct sunxi_rsb_softc *sc, int flags)
{
int error = 0, retry;
/* Wait up to 5 seconds for a transfer to complete */
sc->sc_stat = 0;
for (retry = (flags & I2C_F_POLL) ? 100 : 5; retry > 0; retry--) {
if (flags & I2C_F_POLL) {
sc->sc_stat |= RSB_READ(sc, RSB_STAT_REG);
} else {
error = cv_timedwait(&sc->sc_cv, &sc->sc_lock, hz);
if (error && error != EWOULDBLOCK) {
break;
}
}
if (sc->sc_stat & RSB_STAT_MASK) {
break;
}
if (flags & I2C_F_POLL) {
delay(10000);
}
}
if (retry == 0)
error = EAGAIN;
if (flags & I2C_F_POLL) {
RSB_WRITE(sc, RSB_STAT_REG,
sc->sc_stat & RSB_STAT_MASK);
}
if (error) {
/* Abort transaction */
device_printf(sc->sc_dev, "transfer timeout, error = %d\n",
error);
RSB_WRITE(sc, RSB_CTRL_REG,
RSB_CTRL_ABORT_TRANS);
return error;
}
if (sc->sc_stat & RSB_STAT_LOAD_BSY) {
device_printf(sc->sc_dev, "transfer busy\n");
return EBUSY;
}
if (sc->sc_stat & RSB_STAT_TRANS_ERR) {
device_printf(sc->sc_dev, "transfer error, id 0x%02llx\n",
__SHIFTOUT(sc->sc_stat, RSB_STAT_TRANS_ERR_ID));
return EIO;
}
return 0;
}
static int
sunxi_rsb_rsb_config(struct sunxi_rsb_softc *sc, uint8_t rta, i2c_addr_t da,
int flags)
{
uint32_t dar, ctrl;
KASSERT(mutex_owned(&sc->sc_lock));
RSB_WRITE(sc, RSB_STAT_REG,
RSB_READ(sc, RSB_STAT_REG) & RSB_STAT_MASK);
dar = __SHIFTIN(rta, RSB_DAR_RTA);
dar |= __SHIFTIN(da, RSB_DAR_DA);
RSB_WRITE(sc, RSB_DAR_REG, dar);
RSB_WRITE(sc, RSB_CMD_REG, RSB_CMD_IDX_SRTA);
/* Make sure the controller is idle */
ctrl = RSB_READ(sc, RSB_CTRL_REG);
if (ctrl & RSB_CTRL_START_TRANS) {
device_printf(sc->sc_dev, "device is busy\n");
return EBUSY;
}
/* Start the transfer */
RSB_WRITE(sc, RSB_CTRL_REG,
ctrl | RSB_CTRL_START_TRANS);
return sunxi_rsb_wait(sc, flags);
}
static int
sunxi_rsb_acquire_bus(void *priv, int flags)
{
struct sunxi_rsb_softc *sc = priv;
if (flags & I2C_F_POLL) {
if (!mutex_tryenter(&sc->sc_lock))
return EBUSY;
} else {
mutex_enter(&sc->sc_lock);
}
return 0;
}
static void
sunxi_rsb_release_bus(void *priv, int flags)
{
struct sunxi_rsb_softc *sc = priv;
mutex_exit(&sc->sc_lock);
}
static int
sunxi_rsb_exec(void *priv, i2c_op_t op, i2c_addr_t addr,
const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
{
struct sunxi_rsb_softc *sc = priv;
uint32_t dlen, ctrl;
uint8_t rta;
int error, i;
KASSERT(mutex_owned(&sc->sc_lock));
if (cmdlen != 1 || (len != 1 && len != 2 && len != 4))
return EINVAL;
if (sc->sc_type == SUNXI_RSB && sc->sc_rsb_last_da != addr) {
/* Lookup run-time address for given device address */
for (rta = 0, i = 0; rsb_rtamap[i].rta != 0; i++)
if (rsb_rtamap[i].addr == addr) {
rta = rsb_rtamap[i].rta;
break;
}
if (rta == 0) {
device_printf(sc->sc_dev,
"RTA not known for address %#x\n", addr);
return ENXIO;
}
error = sunxi_rsb_rsb_config(sc, rta, addr, flags);
if (error) {
device_printf(sc->sc_dev,
"SRTA failed, flags = %x, error = %d\n",
flags, error);
sc->sc_rsb_last_da = 0;
return error;
}
sc->sc_rsb_last_da = addr;
}
/* Data byte register */
RSB_WRITE(sc, RSB_DADDR0_REG, *(const uint8_t *)cmdbuf);
if (I2C_OP_WRITE_P(op)) {
uint8_t *pbuf = buf;
uint32_t data;
/* Write data */
switch (len) {
case 1:
data = pbuf[0];
break;
case 2:
data = pbuf[0] | (pbuf[1] << 8);
break;
case 4:
data = pbuf[0] | (pbuf[1] << 8) |
(pbuf[2] << 16) | (pbuf[3] << 24);
break;
default:
return EINVAL;
}
RSB_WRITE(sc, RSB_DATA0_REG, data);
}
if (sc->sc_type == SUNXI_RSB) {
uint8_t cmd;
if (I2C_OP_WRITE_P(op)) {
switch (len) {
case 1: cmd = RSB_CMD_IDX_WR8; break;
case 2: cmd = RSB_CMD_IDX_WR16; break;
case 4: cmd = RSB_CMD_IDX_WR32; break;
default: return EINVAL;
}
} else {
switch (len) {
case 1: cmd = RSB_CMD_IDX_RD8; break;
case 2: cmd = RSB_CMD_IDX_RD16; break;
case 4: cmd = RSB_CMD_IDX_RD32; break;
default: return EINVAL;
}
}
RSB_WRITE(sc, RSB_CMD_REG, cmd);
}
/* Program data length register; if reading, set read/write bit */
dlen = __SHIFTIN(len - 1, RSB_DLEN_ACCESS_LENGTH);
if (I2C_OP_READ_P(op)) {
dlen |= RSB_DLEN_READ_WRITE_FLAG;
}
RSB_WRITE(sc, RSB_DLEN_REG, dlen);
/* Make sure the controller is idle */
ctrl = RSB_READ(sc, RSB_CTRL_REG);
if (ctrl & RSB_CTRL_START_TRANS) {
device_printf(sc->sc_dev, "device is busy\n");
return EBUSY;
}
/* Start the transfer */
RSB_WRITE(sc, RSB_CTRL_REG,
ctrl | RSB_CTRL_START_TRANS);
error = sunxi_rsb_wait(sc, flags);
if (error) {
return error;
}
if (I2C_OP_READ_P(op)) {
uint32_t data = RSB_READ(sc, RSB_DATA0_REG);
switch (len) {
case 4:
*(uint32_t *)buf = data;
break;
case 2:
*(uint16_t *)buf = data & 0xffff;
break;
case 1:
*(uint8_t *)buf = data & 0xff;
break;
default:
return EINVAL;
}
}
return 0;
}

View File

@ -0,0 +1,85 @@
/* $NetBSD: sunxi_rsb.h,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#ifndef _ARM_SUNXI_RSB_H
#define _ARM_SUNXI_RSB_H
#define RSB_CTRL_REG 0x0000
#define RSB_CTRL_START_TRANS __BIT(7)
#define RSB_CTRL_ABORT_TRANS __BIT(6)
#define RSB_CTRL_GLOBAL_INT_ENB __BIT(1)
#define RSB_CTRL_SOFT_RESET __BIT(0)
#define RSB_CCR_REG 0x0004
#define RSB_CCR_SDA_ODLY __BITS(10,8)
#define RSB_CCR_CLK_DIV __BITS(7,0)
#define RSB_INTE_REG 0x0008
#define RSB_INTE_LOAD_BSY_ENB __BIT(2)
#define RSB_INTE_TRANS_ERR_ENB __BIT(1)
#define RSB_INTE_TRANS_OVER_ENB __BIT(0)
#define RSB_STAT_REG 0x000c
#define RSB_STAT_TRANS_ERR_ID __BITS(15,8)
#define RSB_STAT_LOAD_BSY __BIT(2)
#define RSB_STAT_TRANS_ERR __BIT(1)
#define RSB_STAT_TRANS_OVER __BIT(0)
#define RSB_STAT_MASK \
(RSB_STAT_LOAD_BSY | \
RSB_STAT_TRANS_ERR | \
RSB_STAT_TRANS_OVER)
#define RSB_DADDR0_REG 0x0010
#define RSB_DADDR1_REG 0x0014
#define RSB_DLEN_REG 0x0018
#define RSB_DLEN_READ_WRITE_FLAG __BIT(4)
#define RSB_DLEN_ACCESS_LENGTH __BITS(2,0)
#define RSB_DATA0_REG 0x001c
#define RSB_DATA1_REG 0x0020
#define RSB_LCR_REG 0x0024
#define RSB_LCR_SCL_STATE __BIT(5)
#define RSB_LCR_SDA_STATE __BIT(4)
#define RSB_LCR_SCL_CTL __BIT(3)
#define RSB_LCR_SCL_CTL_EN __BIT(2)
#define RSB_LCR_SDA_CTL __BIT(1)
#define RSB_LCR_SDA_CTL_EN __BIT(0)
#define RSB_PMCR_REG 0x0028
#define RSB_PMCR_PMU_INIT_SEND __BIT(31)
#define RSB_PMCR_PMU_INIT_DATA __BITS(23,16)
#define RSB_PMCR_PMU_MODE_CTRL_REG_ADDR __BITS(15,8)
#define RSB_PMCR_PMU_DEVICE_ADDR __BITS(7,0)
#define RSB_CMD_REG 0x002c
#define RSB_CMD_IDX __BITS(7,0)
#define RSB_CMD_IDX_SRTA 0xe8
#define RSB_CMD_IDX_RD8 0x8b
#define RSB_CMD_IDX_RD16 0x9c
#define RSB_CMD_IDX_RD32 0xa6
#define RSB_CMD_IDX_WR8 0x4e
#define RSB_CMD_IDX_WR16 0x59
#define RSB_CMD_IDX_WR32 0x63
#define RSB_DAR_REG 0x0030
#define RSB_DAR_RTA __BITS(23,16)
#define RSB_DAR_DA __BITS(15,0)
#endif /* _ARM_SUNXI_RSB_H */

View File

@ -0,0 +1,174 @@
/* $NetBSD: sunxi_rtc.c,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2014-2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_rtc.c,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/mutex.h>
#include <dev/clock_subr.h>
#include <dev/fdt/fdtvar.h>
#define RTC_YY_MM_DD_REG 0x10
#define SUNXI_RTC_LEAP __BIT(22)
#define SUNXI_RTC_YEAR __BITS(21,16)
#define SUNXI_RTC_MONTH __BITS(11,8)
#define SUNXI_RTC_DAY __BITS(4,0)
#define RTC_HH_MM_SS_REG 0x14
#define SUNXI_RTC_WK_NO __BITS(31,29)
#define SUNXI_RTC_HOUR __BITS(20,16)
#define SUNXI_RTC_MINUTE __BITS(13,8)
#define SUNXI_RTC_SECOND __BITS(5,0)
#define SUNXI_RTC_BASE_YEAR 2000
static const char * const compatible[] = {
"allwinner,sun6i-a31-rtc",
NULL
};
struct sunxi_rtc_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
struct todr_chip_handle sc_todr;
};
#define RTC_READ(sc, reg) \
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
#define RTC_WRITE(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
static int sunxi_rtc_match(device_t, cfdata_t, void *);
static void sunxi_rtc_attach(device_t, device_t, void *);
static int sunxi_rtc_gettime(todr_chip_handle_t, struct clock_ymdhms *);
static int sunxi_rtc_settime(todr_chip_handle_t, struct clock_ymdhms *);
CFATTACH_DECL_NEW(sunxi_rtc, sizeof(struct sunxi_rtc_softc),
sunxi_rtc_match, sunxi_rtc_attach, NULL, NULL);
static int
sunxi_rtc_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
sunxi_rtc_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_rtc_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
bus_addr_t addr;
bus_size_t size;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
sc->sc_dev = self;
sc->sc_bst = faa->faa_bst;
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
aprint_error(": couldn't map registers\n");
return;
}
aprint_naive("\n");
aprint_normal(": RTC\n");
sc->sc_todr.todr_gettime_ymdhms = sunxi_rtc_gettime;
sc->sc_todr.todr_settime_ymdhms = sunxi_rtc_settime;
sc->sc_todr.cookie = sc;
fdtbus_todr_attach(self, phandle, &sc->sc_todr);
}
static int
sunxi_rtc_gettime(todr_chip_handle_t tch, struct clock_ymdhms *dt)
{
struct sunxi_rtc_softc *sc = tch->cookie;
const uint32_t yymmdd = RTC_READ(sc, RTC_YY_MM_DD_REG);
const uint32_t hhmmss = RTC_READ(sc, RTC_HH_MM_SS_REG);
dt->dt_year = __SHIFTOUT(yymmdd, SUNXI_RTC_YEAR) + SUNXI_RTC_BASE_YEAR;
dt->dt_mon = __SHIFTOUT(yymmdd, SUNXI_RTC_MONTH);
dt->dt_day = __SHIFTOUT(yymmdd, SUNXI_RTC_DAY);
dt->dt_wday = __SHIFTOUT(hhmmss, SUNXI_RTC_WK_NO);
dt->dt_hour = __SHIFTOUT(hhmmss, SUNXI_RTC_HOUR);
dt->dt_min = __SHIFTOUT(hhmmss, SUNXI_RTC_MINUTE);
dt->dt_sec = __SHIFTOUT(hhmmss, SUNXI_RTC_SECOND);
return 0;
}
static int
sunxi_rtc_settime(todr_chip_handle_t tch, struct clock_ymdhms *dt)
{
struct sunxi_rtc_softc *sc = tch->cookie;
uint32_t yymmdd, hhmmss, maxyear;
/*
* Sanity check the date before writing it back
*/
if (dt->dt_year < SUNXI_RTC_BASE_YEAR) {
aprint_normal_dev(sc->sc_dev, "year pre the epoch: %llu, "
"not writing back time\n", dt->dt_year);
return EIO;
}
maxyear = __SHIFTOUT(0xffffffff, SUNXI_RTC_YEAR) + SUNXI_RTC_BASE_YEAR;
if (dt->dt_year > maxyear) {
aprint_normal_dev(sc->sc_dev, "year exceeds available field:"
" %llu, not writing back time\n", dt->dt_year);
return EIO;
}
yymmdd = __SHIFTIN(dt->dt_year - SUNXI_RTC_BASE_YEAR, SUNXI_RTC_YEAR);
yymmdd |= __SHIFTIN(dt->dt_mon, SUNXI_RTC_MONTH);
yymmdd |= __SHIFTIN(dt->dt_day, SUNXI_RTC_DAY);
hhmmss = __SHIFTIN(dt->dt_wday, SUNXI_RTC_WK_NO);
hhmmss |= __SHIFTIN(dt->dt_hour, SUNXI_RTC_HOUR);
hhmmss |= __SHIFTIN(dt->dt_min, SUNXI_RTC_MINUTE);
hhmmss |= __SHIFTIN(dt->dt_sec, SUNXI_RTC_SECOND);
RTC_WRITE(sc, RTC_YY_MM_DD_REG, yymmdd);
RTC_WRITE(sc, RTC_HH_MM_SS_REG, hhmmss);
return 0;
}

View File

@ -0,0 +1,148 @@
/* $NetBSD: sunxi_twi.c,v 1.2.4.2 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_twi.c,v 1.2.4.2 2017/07/18 19:13:09 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/gttwsivar.h>
#include <dev/fdt/fdtvar.h>
static int sunxi_twi_match(device_t, cfdata_t, void *);
static void sunxi_twi_attach(device_t, device_t, void *);
static const char * const compatible[] = {
"allwinner,sun6i-a31-i2c",
NULL
};
CFATTACH_DECL_NEW(sunxi_twi, sizeof(struct gttwsi_softc),
sunxi_twi_match, sunxi_twi_attach, NULL, NULL);
static i2c_tag_t
sunxi_twi_get_tag(device_t dev)
{
struct gttwsi_softc * const sc = device_private(dev);
return &sc->sc_i2c;
}
const struct fdtbus_i2c_controller_func sunxi_twi_funcs = {
.get_tag = sunxi_twi_get_tag,
};
static int
sunxi_twi_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
sunxi_twi_attach(device_t parent, device_t self, void *aux)
{
struct gttwsi_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
struct i2cbus_attach_args iba;
const int phandle = faa->faa_phandle;
bus_space_tag_t bst = faa->faa_bst;
bus_space_handle_t bsh;
prop_dictionary_t devs;
uint32_t address_cells;
struct fdtbus_reset *rst;
struct clk *clk;
char intrstr[128];
bus_addr_t addr;
bus_size_t size;
void *ih;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
if (bus_space_map(bst, addr, size, 0, &bsh) != 0) {
aprint_error(": couldn't map registers\n");
return;
}
if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
aprint_error(": failed to decode interrupt\n");
return;
}
if ((clk = fdtbus_clock_get_index(phandle, 0)) != NULL)
if (clk_enable(clk) != 0) {
aprint_error(": couldn't enable clock\n");
return;
}
if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL)
if (fdtbus_reset_deassert(rst) != 0) {
aprint_error(": couldn't de-assert reset\n");
return;
}
gttwsi_attach_subr(self, bst, bsh);
ih = fdtbus_intr_establish(phandle, 0, IPL_VM, 0, gttwsi_intr, sc);
if (ih == NULL) {
aprint_error_dev(self, "couldn't establish interrupt on %s\n",
intrstr);
return;
}
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
fdtbus_register_i2c_controller(self, phandle, &sunxi_twi_funcs);
devs = prop_dictionary_create();
if (of_getprop_uint32(phandle, "#address-cells", &address_cells))
address_cells = 1;
of_enter_i2c_devs(devs, phandle, address_cells * 4, 0);
memset(&iba, 0, sizeof(iba));
iba.iba_tag = &sc->sc_i2c;
iba.iba_child_devices = prop_dictionary_get(devs, "i2c-child-devices");
if (iba.iba_child_devices)
prop_object_retain(iba.iba_child_devices);
else
iba.iba_child_devices = prop_array_create();
prop_object_release(devs);
config_found_ia(self, "i2cbus", &iba, iicbus_print);
}

View File

@ -0,0 +1,235 @@
/* $NetBSD: sunxi_usbphy.c,v 1.3.4.2 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sunxi_usbphy.c,v 1.3.4.2 2017/07/18 19:13:09 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <dev/fdt/fdtvar.h>
#define OTG_PHY_CFG 0x20
#define OTG_PHY_ROUTE_OTG __BIT(0)
#define HCI_ICR 0x00
#define HCI_AHB_INCR8 __BIT(10)
#define HCI_AHB_INCR4 __BIT(9)
#define HCI_AHB_INCRX_ALIGN __BIT(8)
#define HCI_ULPI_BYPASS __BIT(0)
#define PMU_UNK_H3 0x10
#define PMU_UNK_H3_CLR __BIT(1)
static int sunxi_usbphy_match(device_t, cfdata_t, void *);
static void sunxi_usbphy_attach(device_t, device_t, void *);
enum sunxi_usbphy_type {
USBPHY_A31,
USBPHY_H3,
};
static const struct of_compat_data compat_data[] = {
{ "allwinner,sun6i-a31-usb-phy", USBPHY_A31 },
{ "allwinner,sun8i-h3-usb-phy", USBPHY_H3 },
{ NULL }
};
#define SUNXI_MAXUSBPHY 4
struct sunxi_usbphy {
u_int phy_index;
bus_space_handle_t phy_bsh;
struct fdtbus_regulator *phy_reg;
};
struct sunxi_usbphy_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh_phy_ctrl;
enum sunxi_usbphy_type sc_type;
struct sunxi_usbphy sc_phys[SUNXI_MAXUSBPHY];
u_int sc_nphys;
struct fdtbus_gpio_pin *sc_gpio_id_det;
struct fdtbus_gpio_pin *sc_gpio_vbus_det;
};
#define USBPHY_READ(sc, id, reg) \
bus_space_read_4((sc)->sc_bst, \
(sc)->sc_phys[(id)].phy_bsh, (reg))
#define USBPHY_WRITE(sc, id, reg, val) \
bus_space_write_4((sc)->sc_bst, \
(sc)->sc_phys[(id)].phy_bsh, (reg), (val))
CFATTACH_DECL_NEW(sunxi_usbphy, sizeof(struct sunxi_usbphy_softc),
sunxi_usbphy_match, sunxi_usbphy_attach, NULL, NULL);
static bool
sunxi_usbphy_vbus_detect(struct sunxi_usbphy_softc *sc)
{
if (sc->sc_gpio_vbus_det)
return fdtbus_gpio_read(sc->sc_gpio_vbus_det);
return 1;
}
static void *
sunxi_usbphy_acquire(device_t dev, const void *data, size_t len)
{
struct sunxi_usbphy_softc * const sc = device_private(dev);
if (len != 4)
return NULL;
const int phy_id = be32dec(data);
if (phy_id >= sc->sc_nphys)
return NULL;
return &sc->sc_phys[phy_id];
}
static void
sunxi_usbphy_release(device_t dev, void *priv)
{
}
static int
sunxi_usbphy_enable(device_t dev, void *priv, bool enable)
{
struct sunxi_usbphy_softc * const sc = device_private(dev);
struct sunxi_usbphy * const phy = priv;
uint32_t val;
if (phy->phy_index > 0) {
/* Enable passby */
val = USBPHY_READ(sc, phy->phy_index, HCI_ICR);
val |= HCI_ULPI_BYPASS;
val |= HCI_AHB_INCR8;
val |= HCI_AHB_INCR4;
val |= HCI_AHB_INCRX_ALIGN;
USBPHY_WRITE(sc, phy->phy_index, HCI_ICR, val);
}
if (sc->sc_type == USBPHY_H3) {
/* H3-specific */
val = USBPHY_READ(sc, phy->phy_index, PMU_UNK_H3);
val &= ~PMU_UNK_H3_CLR;
USBPHY_WRITE(sc, phy->phy_index, PMU_UNK_H3, val);
}
if (phy->phy_reg == NULL)
return 0;
if (enable) {
/* If an external vbus is detected, do not enable phy 0 */
if (phy->phy_index == 0 && sunxi_usbphy_vbus_detect(sc))
return 0;
return fdtbus_regulator_enable(phy->phy_reg);
} else {
return fdtbus_regulator_disable(phy->phy_reg);
}
}
const struct fdtbus_phy_controller_func sunxi_usbphy_funcs = {
.acquire = sunxi_usbphy_acquire,
.release = sunxi_usbphy_release,
.enable = sunxi_usbphy_enable,
};
static int
sunxi_usbphy_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compat_data(faa->faa_phandle, compat_data);
}
static void
sunxi_usbphy_attach(device_t parent, device_t self, void *aux)
{
struct sunxi_usbphy_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
struct fdtbus_reset *rst;
struct sunxi_usbphy *phy;
struct clk *clk;
bus_addr_t addr;
bus_size_t size;
char pname[20];
u_int n;
sc->sc_dev = self;
sc->sc_bst = faa->faa_bst;
sc->sc_type = of_search_compatible(phandle, compat_data)->data;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get phy ctrl registers\n");
return;
}
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh_phy_ctrl) != 0) {
aprint_error(": couldn't map phy ctrl registers\n");
return;
}
for (sc->sc_nphys = 0; sc->sc_nphys < SUNXI_MAXUSBPHY; sc->sc_nphys++) {
if (fdtbus_get_reg(phandle, sc->sc_nphys + 1, &addr, &size) != 0)
break;
phy = &sc->sc_phys[sc->sc_nphys];
phy->phy_index = sc->sc_nphys;
if (bus_space_map(sc->sc_bst, addr, size, 0, &phy->phy_bsh) != 0) {
aprint_error(": failed to map reg #%d\n", sc->sc_nphys);
return;
}
/* Get optional regulator */
snprintf(pname, sizeof(pname), "usb%d_vbus-supply", sc->sc_nphys);
phy->phy_reg = fdtbus_regulator_acquire(phandle, pname);
}
/* Enable clocks */
for (n = 0; (clk = fdtbus_clock_get_index(phandle, n)) != NULL; n++)
if (clk_enable(clk) != 0) {
aprint_error(": couldn't enable clock #%d\n", n);
return;
}
/* De-assert resets */
for (n = 0; (rst = fdtbus_reset_get_index(phandle, n)) != NULL; n++)
if (fdtbus_reset_deassert(rst) != 0) {
aprint_error(": couldn't de-assert reset #%d\n", n);
return;
}
aprint_naive("\n");
aprint_normal(": USB PHY\n");
fdtbus_register_phy_controller(self, phandle, &sunxi_usbphy_funcs);
}

View File

@ -1,301 +1,94 @@
#
# $NetBSD: EXYNOS,v 1.14 2017/04/16 15:49:26 jmcneill Exp $
# $NetBSD: EXYNOS,v 1.14.4.1 2017/07/18 19:13:09 snj Exp $
#
# ODROID-XU -- ODROID-XU4 Exynos5422 based kernel
# Samsung Exynos SoC kernel
#
include "arch/evbarm/conf/std.exynos"
include "arch/evbarm/conf/GENERIC.common"
no makeoptions CPUFLAGS
makeoptions CPUFLAGS="-mcpu=cortex-a7 -mfpu=neon"
no makeoptions BOARDTYPE
makeoptions BOARDTYPE="hardkernel_odroid_xu4"
no makeoptions KERNEL_BASE_PHYS
no makeoptions KERNEL_BASE_VIRT
makeoptions KERNEL_BASE_PHYS="0x80000000"
makeoptions KERNEL_BASE_VIRT="0x80000000"
options PMAP_NEED_ALLOC_POOLPAGE
options MEMSIZE=2048
# estimated number of users
maxusers 8
# Standard system options
options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT
#options NTP # NTP phase/frequency locked loop
# CPU options
options CPU_CORTEX
options CPU_CORTEXA7
options CPU_CORTEXA15
options EXYNOS5422
#options MULTIPROCESSOR
options SOC_EXYNOS5422
options MULTIPROCESSOR
options FDT # not really but soon
pseudo-device openfirm # jmcneill: oops, fdtbus should depend on
# openfirm. don't let me forget.
pseudo-device openfirm # /dev/openfirm
options PMAPCOUNTERS
options BUSDMA_COUNTERS
options EXYNOS_CONSOLE_EARLY
#options UVMHIST
options USBHIST
options USBHIST_SIZE=100000
#options UVMHIST_PRINT,KERNHIST_DELAY=0
options __HAVE_MM_MD_DIRECT_MAPPED_PHYS
#options PMAP_NEED_ALLOC_POOLPAGE
# Specify the memory size in megabytes (optional).
#options MEMSIZE=2048
# File systems
file-system FFS # UFS
#file-system LFS # log-structured file system
file-system MFS # memory file system
file-system NFS # Network file system
#file-system ADOSFS # AmigaDOS-compatible file system
#file-system EXT2FS # second extended file system (linux)
#file-system CD9660 # ISO 9660 + Rock Ridge file system
file-system MSDOSFS # MS-DOS file system
#file-system FDESC # /dev/fd
file-system KERNFS # /kern
#file-system NULLFS # loopback file system
file-system PROCFS # /proc
#file-system PUFFS # Userspace file systems (e.g. ntfs-3g & sshfs)
#file-system UMAPFS # NULLFS + uid and gid remapping
#file-system UNION # union file system
file-system TMPFS # memory file system
file-system PTYFS # /dev/pts/N support
# File system options
#options QUOTA # legacy UFS quotas
#options QUOTA2 # new, in-filesystem UFS quotas
#options DISKLABEL_EI # disklabel Endian Independent support
#options FFS_EI # FFS Endian Independent support
options NFSSERVER
options WAPBL # File system journaling support
#options FFS_NO_SNAPSHOT # No FFS snapshot support
# Networking options
#options GATEWAY # packet forwarding
options INET # IP + ICMP + TCP + UDP
options INET6 # IPV6
#options IPSEC # IP security
#options IPSEC_DEBUG # debug for IP security
#options MROUTING # IP multicast routing
#options PIM # Protocol Independent Multicast
#options NETATALK # AppleTalk networking
#options PPP_BSDCOMP # BSD-Compress compression support for PPP
#options PPP_DEFLATE # Deflate compression support for PPP
#options PPP_FILTER # Active filter support for PPP (requires bpf)
#options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG
#options NFS_BOOT_BOOTP
#options NFS_BOOT_DHCP
#options NFS_BOOT_BOOTSTATIC
#options NFS_BOOTSTATIC_MYIP="\"192.168.0.22\""
#options NFS_BOOTSTATIC_GWIP="\"192.168.0.1\""
#options NFS_BOOTSTATIC_MASK="\"255.255.255.0\""
#options NFS_BOOTSTATIC_SERVADDR="\"192.168.0.5\""
#options NFS_BOOTSTATIC_SERVER="\"192.168.0.5:/stuff/nfs/odroid\""
#options NFS_BOOT_RWSIZE=1024
# Compatibility options
options COMPAT_NETBSD32 # allow running arm (e.g. non-earm) binaries
#options COMPAT_43 # 4.3BSD compatibility.
#options COMPAT_09 # NetBSD 0.9,
#options COMPAT_10 # NetBSD 1.0,
#options COMPAT_11 # NetBSD 1.1,
#options COMPAT_12 # NetBSD 1.2,
#options COMPAT_13 # NetBSD 1.3,
#options COMPAT_14 # NetBSD 1.4,
#options COMPAT_15 # NetBSD 1.5,
#options COMPAT_16 # NetBSD 1.6,
#options COMPAT_20 # NetBSD 2.0,
#options COMPAT_30 # NetBSD 3.0,
#options COMPAT_40 # NetBSD 4.0,
#options COMPAT_50 # NetBSD 5.0,
options COMPAT_60 # NetBSD 6.0, and
options COMPAT_70 # NetBSD 7.0 binary compatibility.
#options TCP_COMPAT_42 # 4.2BSD TCP/IP bug compat. Not recommended.
#options COMPAT_BSDPTY # /dev/[pt]ty?? ptys.
# Shared memory options
options SYSVMSG # System V-like message queues
options SYSVSEM # System V-like semaphores
options SYSVSHM # System V-like memory sharing
# Device options
#options MEMORY_DISK_HOOKS # boottime setup of ramdisk
#options MEMORY_DISK_ROOT_SIZE=8192 # Size in blocks
#options MEMORY_DISK_DYNAMIC
#options MINIROOTSIZE=1000 # Size in blocks
#options MEMORY_DISK_IS_ROOT # use memory disk as root
# Wedge support
options DKWEDGE_AUTODISCOVER # Automatically add dk(4) instances
options DKWEDGE_METHOD_GPT # Supports GPT partitions as wedges
# Miscellaneous kernel options
options KTRACE # system call tracing, a la ktrace(1)
#options SCSIVERBOSE # Verbose SCSI errors
#options MIIVERBOSE # Verbose MII autoconfuration messages
options DDB_KEYCODE=0x40
#options USERCONF # userconf(4) support
#options PIPE_SOCKETPAIR # smaller, but slower pipe(2)
# Development and Debugging options
#options PERFCTRS # performance counters
options DIAGNOSTIC # internal consistency checks
options DEBUG
options LOCKDEBUG
options PMAP_DEBUG # Enable pmap_debug_level code
#options DIAGNOSTIC # internal consistency checks
#options DEBUG
#options LOCKDEBUG
#options PMAP_DEBUG # Enable pmap_debug_level code
#options IPKDB # remote kernel debugging
options VERBOSE_INIT_ARM # verbose bootstraping messages
options DDB # in-kernel debugger
options DDB_ONPANIC=1
options DDB_HISTORY_SIZE=100 # Enable history editing in DDB
options DDB_VERBOSE_HELP
#options KGDB
#options VERBOSE_INIT_ARM # verbose bootstrapping messages
# SSCOMnCONSOLE is required for early init messages from VERBOSE_INIT_ARM.
#options SSCOM2CONSOLE
makeoptions DEBUG="-g" # compile full symbol table
makeoptions COPY_SYMTAB=1
## USB Debugging options
options USB_DEBUG
options EHCI_DEBUG
options OHCI_DEBUG
options UHUB_DEBUG
options USBVERBOSE
# Valid options for BOOT_ARGS:
# single Boot to single user only
# kdb Give control to kernel debugger
# ask Ask for file name to reboot from
# memorydisk=<n> Set memorydisk size to <n> KB
# quiet Show aprint_naive output
# verbose Show aprint_normal and aprint_verbose output
#options BOOT_ARGS="\"\""
options BOOT_ARGS="\"verbose\""
config netbsd root on ? type ?
# The main bus device
mainbus0 at root
# The boot cpu and secondary CPUs
cpu0 at mainbus?
cpu* at mainbus? # Multiprocessor
# core devices
armperiph0 at mainbus?
armgic0 at armperiph? # Interrupt Controller
armgtmr0 at armperiph? # Generic Timer
# On-board I/O
exynosfdt0 at mainbus?
# Device tree support
armfdt0 at root
fdt* at fdtbus?
fregulator* at fdt?
# CPUs
cpus* at fdt? pass 0
cpu* at cpus?
#interrupt controller
exyointr0 at fdt?
gic* at fdt?
fclock* at fdt? pass 4
fregulator* at fdt? pass 4
gpiokeys* at fdt?
# Timer
mct* at fdt? # Exynos Multi Core Timer (MCT)
armgtmr0 at mct? # ARM Generic Timer
# Interrupt controller
exyointr* at fdt? pass 1
gic* at fdt? pass 1 # GIC
armgic0 at gic?
# Clock controller
exy5422clk* at fdt? # Exynos5422 clock controller
exy5410clk* at fdt? pass 3 # Exynos5410 clock controller
exy5422clk* at fdt? pass 3 # Exynos5422 clock controller
# Integrated Samsung UARTs
sscom* at fdt? # UART ?
# Exynos Watchdog Timer
exyowdt* at fdt? # watchdog
# Exynos chip id
chipid* at fdt?
# Exynos system MMUs
sysmmu* at fdt?
# Exynos RTC
exyortc* at fdt?
# Exynos Multi Core timer (MCT)
mct* at fdt?
# GPIO
exyopctl* at fdt?
# GPIO controller
exyopctl* at fdt? pass 2 # GPIO
gpio* at gpiobus?
# On-board USB 2.0
exyousbphy* at fdt?
ohci* at fdt?
ehci* at fdt?
usb* at ohci?
usb* at ehci?
# Exynos SoC support
chipid* at fdt?
sysmmu* at fdt?
# On-board USB 3.0
exyousb* at fdt?
#xhci* at fdt?
#usb* at xhci?
# UART
sscom* at fdt? # UART
# I2C devices
exyoi2c* at fdt?
#i2c* at exyoi2c?
# I2C
exyoi2c* at fdt? # I2C
iic* at exyoi2c?
# SD/MMC
dwcmmc* at fdt?
# RTC
#exyortc* at fdt? # RTC
# SDMMC
dwcmmc* at fdt? # SDMMC
sdmmc* at dwcmmc?
ld0 at sdmmc0
ld1 at sdmmc1
ld2 at sdmmc2
ld3 at sdmmc3
ld* at sdmmc?
# MISSING SUPPORT
# eMMC
# uSD
# SPI
# ADC
# PMIC (via I2C #4)
# PWM for Cooling fan
# HDMI
# I2S
# GPU
# USB
exyousbphy* at fdt?
exyousb* at fdt?
ohci* at fdt? # OUSB
ehci* at fdt? # EUSB
usb* at ohci?
usb* at ehci?
# serial console connectivity
options SSCOM2CONSOLE, CONSPEED=115200
# include all USB devices
include "dev/usb/usbdevices.config"
midi* at midibus?
# Pseudo-Devices
# disk/mass storage pseudo-devices
#pseudo-device md # memory disk device (ramdisk)
#pseudo-device vnd # disk-like interface to files
#pseudo-device fss # file system snapshot device
#pseudo-device putter # for puffs and pud
pseudo-device drvctl # driver control
# network pseudo-devices
pseudo-device bpfilter # Berkeley packet filter
pseudo-device loop # network loopback
#pseudo-device kttcp # network loopback
# miscellaneous pseudo-devices
pseudo-device pty # pseudo-terminals
#options RND_COM
#pseudo-device clockctl # user control of clock subsystem
pseudo-device ksyms # /dev/ksyms
#pseudo-device lockstat # lock profiling
cinclude "arch/evbarm/conf/EXYNOS.local"

View File

@ -1,248 +0,0 @@
#
# $NetBSD: ODROID-U,v 1.20 2017/02/19 07:47:00 rin Exp $
#
# ODROID-U -- ODROID-U{2,3} series Exynos4x12(P) based kernel
#
include "arch/evbarm/conf/std.odroid"
# estimated number of users
maxusers 32
# Standard system options
options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT
#options NTP # NTP phase/frequency locked loop
# CPU options
options CPU_CORTEX
options CPU_CORTEXA9
options EXYNOS4212
options EXYNOS4412
options EXYNOS4412P
#options MULTIPROCESSOR
options PMAPCOUNTERS
options BUSDMA_COUNTERS
options EXYNOS_CONSOLE_EARLY
#options UVMHIST
#options UVMHIST_PRINT,KERNHIST_DELAY=0
#options KERNHIST
#options USB_DEBUG
#options USBHIST_SIZE=100000
options __HAVE_MM_MD_DIRECT_MAPPED_PHYS
options PMAP_NEED_ALLOC_POOLPAGE
# Specify the memory size in megabytes (optional).
#options MEMSIZE=2048
# File systems
file-system FFS # UFS
#file-system LFS # log-structured file system
file-system MFS # memory file system
file-system NFS # Network file system
#file-system ADOSFS # AmigaDOS-compatible file system
#file-system EXT2FS # second extended file system (linux)
#file-system CD9660 # ISO 9660 + Rock Ridge file system
file-system MSDOSFS # MS-DOS file system
#file-system FDESC # /dev/fd
file-system KERNFS # /kern
#file-system NULLFS # loopback file system
file-system PROCFS # /proc
#file-system PUFFS # Userspace file systems (e.g. ntfs-3g & sshfs)
#file-system UMAPFS # NULLFS + uid and gid remapping
#file-system UNION # union file system
file-system TMPFS # memory file system
file-system PTYFS # /dev/pts/N support
# File system options
#options QUOTA # legacy UFS quotas
#options QUOTA2 # new, in-filesystem UFS quotas
#options DISKLABEL_EI # disklabel Endian Independent support
#options FFS_EI # FFS Endian Independent support
#options NFSSERVER
options WAPBL # File system journaling support
#options FFS_NO_SNAPSHOT # No FFS snapshot support
# Networking options
#options GATEWAY # packet forwarding
options INET # IP + ICMP + TCP + UDP
options INET6 # IPV6
#options IPSEC # IP security
#options IPSEC_DEBUG # debug for IP security
#options MROUTING # IP multicast routing
#options PIM # Protocol Independent Multicast
#options NETATALK # AppleTalk networking
#options PPP_BSDCOMP # BSD-Compress compression support for PPP
#options PPP_DEFLATE # Deflate compression support for PPP
#options PPP_FILTER # Active filter support for PPP (requires bpf)
#options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG
options NFS_BOOT_BOOTP
options NFS_BOOT_DHCP
#options NFS_BOOT_BOOTSTATIC
#options NFS_BOOTSTATIC_MYIP="\"192.168.1.4\""
#options NFS_BOOTSTATIC_GWIP="\"192.168.1.1\""
#options NFS_BOOTSTATIC_MASK="\"255.255.255.0\""
#options NFS_BOOTSTATIC_SERVADDR="\"192.168.1.1\""
#options NFS_BOOTSTATIC_SERVER="\"192.168.1.1:/nfs/sdp2430\""
options NFS_BOOT_RWSIZE=1024
# Compatibility options
options COMPAT_NETBSD32 # allow running arm (e.g. non-earm) binaries
#options COMPAT_43 # 4.3BSD compatibility.
#options COMPAT_09 # NetBSD 0.9,
#options COMPAT_10 # NetBSD 1.0,
#options COMPAT_11 # NetBSD 1.1,
#options COMPAT_12 # NetBSD 1.2,
#options COMPAT_13 # NetBSD 1.3,
#options COMPAT_14 # NetBSD 1.4,
#options COMPAT_15 # NetBSD 1.5,
#options COMPAT_16 # NetBSD 1.6,
#options COMPAT_20 # NetBSD 2.0,
options COMPAT_30 # NetBSD 3.0,
options COMPAT_40 # NetBSD 4.0,
options COMPAT_50 # NetBSD 5.0,
options COMPAT_60 # NetBSD 6.0, and
options COMPAT_70 # NetBSD 7.0 binary compatibility.
#options TCP_COMPAT_42 # 4.2BSD TCP/IP bug compat. Not recommended.
#options COMPAT_BSDPTY # /dev/[pt]ty?? ptys.
# Shared memory options
options SYSVMSG # System V-like message queues
options SYSVSEM # System V-like semaphores
options SYSVSHM # System V-like memory sharing
# Device options
#options MEMORY_DISK_HOOKS # boottime setup of ramdisk
#options MEMORY_DISK_ROOT_SIZE=8192 # Size in blocks
#options MEMORY_DISK_DYNAMIC
#options MINIROOTSIZE=1000 # Size in blocks
#options MEMORY_DISK_IS_ROOT # use memory disk as root
# Wedge support
options DKWEDGE_AUTODISCOVER # Automatically add dk(4) instances
options DKWEDGE_METHOD_GPT # Supports GPT partitions as wedges
# Miscellaneous kernel options
options KTRACE # system call tracing, a la ktrace(1)
#options SCSIVERBOSE # Verbose SCSI errors
options MIIVERBOSE # Verbose MII autoconfuration messages
#options DDB_KEYCODE=0x40
#options USERCONF # userconf(4) support
#options PIPE_SOCKETPAIR # smaller, but slower pipe(2)
# Development and Debugging options
#options PERFCTRS # performance counters
options DIAGNOSTIC # internal consistency checks
options DEBUG
options LOCKDEBUG
#options PMAP_DEBUG # Enable pmap_debug_level code
#options IPKDB # remote kernel debugging
options VERBOSE_INIT_ARM # verbose bootstraping messages
options DDB # in-kernel debugger
options DDB_ONPANIC=1
options DDB_HISTORY_SIZE=100 # Enable history editing in DDB
#options KGDB
makeoptions DEBUG="-g" # compile full symbol table
makeoptions COPY_SYMTAB=1
## USB Debugging options
options USB_DEBUG
options EHCI_DEBUG
options OHCI_DEBUG
options UHUB_DEBUG
options USBVERBOSE
# Valid options for BOOT_ARGS:
# single Boot to single user only
# kdb Give control to kernel debugger
# ask Ask for file name to reboot from
# memorydisk=<n> Set memorydisk size to <n> KB
# quiet Show aprint_naive output
# verbose Show aprint_normal and aprint_verbose output
options BOOT_ARGS="\"verbose\""
config netbsd root on ? type ?
# The main bus device
mainbus0 at root
# The boot cpu and secondary CPUs
cpu0 at mainbus?
#cpu? at mainbus? # Multiprocessor
# A9 core devices
armperiph0 at mainbus?
armgic0 at armperiph? # Interrupt Controller
arml2cc0 at armperiph? # L2 Cache Controller
# Exynos SoC
exyo0 at mainbus?
# Integrated Samsung devices
mct0 at exyo0
# Integrated Samsung UARTs
sscom0 at exyo0 port 0 # UART0, expansion
sscom1 at exyo0 port 1 # UART1, console
# Exynos Watchdog Timer
exyowdt0 at exyo0 flags 0 # watchdog
# GPIO
exyogpio0 at exyo0
gpio* at exyogpio?
# On-board USB
exyousb* at exyo0
ohci* at exyousb?
ehci* at exyousb?
usb* at ohci?
usb* at ehci?
# Network phy for the LAN9730
ukphy* at mii? phy ? # generic unknown PHYs
# I2C devices
exyoiic0 at exyo0
iic* at exyoiic?
# serial console connectivity
options SSCOM1CONSOLE, CONSPEED=115200
# include all USB devices
include "dev/usb/usbdevices.config"
midi* at midibus?
# Pseudo-Devices
# disk/mass storage pseudo-devices
#pseudo-device md # memory disk device (ramdisk)
#pseudo-device vnd # disk-like interface to files
#pseudo-device fss # file system snapshot device
#pseudo-device putter # for puffs and pud
pseudo-device drvctl # driver control
# network pseudo-devices
pseudo-device bpfilter # Berkeley packet filter
pseudo-device loop # network loopback
#pseudo-device kttcp # network loopback
# miscellaneous pseudo-devices
pseudo-device pty # pseudo-terminals
#options RND_COM
#pseudo-device clockctl # user control of clock subsystem
pseudo-device ksyms # /dev/ksyms
#pseudo-device lockstat # lock profiling

View File

@ -1,249 +0,0 @@
#
# $NetBSD: ODROID-XU,v 1.7 2017/02/19 07:47:00 rin Exp $
#
# ODROID-XU -- ODROID-XU Exynos5410 based kernel
#
include "arch/evbarm/conf/std.odroid"
# estimated number of users
maxusers 32
# Standard system options
options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT
#options NTP # NTP phase/frequency locked loop
# CPU options
options CPU_CORTEX
options CPU_CORTEXA7
options CPU_CORTEXA15
options EXYNOS5410
#options MULTIPROCESSOR
options PMAPCOUNTERS
options BUSDMA_COUNTERS
options EXYNOS_CONSOLE_EARLY
#options UVMHIST
options USB_DEBUG
options USBHIST_SIZE=100000
#options UVMHIST_PRINT,KERNHIST_DELAY=0
options __HAVE_MM_MD_DIRECT_MAPPED_PHYS
options PMAP_NEED_ALLOC_POOLPAGE
# Specify the memory size in megabytes (optional).
#options MEMSIZE=2048
# File systems
file-system FFS # UFS
#file-system LFS # log-structured file system
file-system MFS # memory file system
file-system NFS # Network file system
#file-system ADOSFS # AmigaDOS-compatible file system
#file-system EXT2FS # second extended file system (linux)
#file-system CD9660 # ISO 9660 + Rock Ridge file system
file-system MSDOSFS # MS-DOS file system
#file-system FDESC # /dev/fd
file-system KERNFS # /kern
#file-system NULLFS # loopback file system
file-system PROCFS # /proc
#file-system PUFFS # Userspace file systems (e.g. ntfs-3g & sshfs)
#file-system UMAPFS # NULLFS + uid and gid remapping
#file-system UNION # union file system
file-system TMPFS # memory file system
file-system PTYFS # /dev/pts/N support
# File system options
#options QUOTA # legacy UFS quotas
#options QUOTA2 # new, in-filesystem UFS quotas
#options DISKLABEL_EI # disklabel Endian Independent support
#options FFS_EI # FFS Endian Independent support
#options NFSSERVER
options WAPBL # File system journaling support
#options FFS_NO_SNAPSHOT # No FFS snapshot support
# Networking options
#options GATEWAY # packet forwarding
options INET # IP + ICMP + TCP + UDP
options INET6 # IPV6
#options IPSEC # IP security
#options IPSEC_DEBUG # debug for IP security
#options MROUTING # IP multicast routing
#options PIM # Protocol Independent Multicast
#options NETATALK # AppleTalk networking
#options PPP_BSDCOMP # BSD-Compress compression support for PPP
#options PPP_DEFLATE # Deflate compression support for PPP
#options PPP_FILTER # Active filter support for PPP (requires bpf)
#options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG
options NFS_BOOT_BOOTP
options NFS_BOOT_DHCP
#options NFS_BOOT_BOOTSTATIC
#options NFS_BOOTSTATIC_MYIP="\"192.168.1.4\""
#options NFS_BOOTSTATIC_GWIP="\"192.168.1.1\""
#options NFS_BOOTSTATIC_MASK="\"255.255.255.0\""
#options NFS_BOOTSTATIC_SERVADDR="\"192.168.1.1\""
#options NFS_BOOTSTATIC_SERVER="\"192.168.1.1:/nfs/sdp2430\""
options NFS_BOOT_RWSIZE=1024
# Compatibility options
options COMPAT_NETBSD32 # allow running arm (e.g. non-earm) binaries
#options COMPAT_43 # 4.3BSD compatibility.
#options COMPAT_09 # NetBSD 0.9,
#options COMPAT_10 # NetBSD 1.0,
#options COMPAT_11 # NetBSD 1.1,
#options COMPAT_12 # NetBSD 1.2,
#options COMPAT_13 # NetBSD 1.3,
#options COMPAT_14 # NetBSD 1.4,
#options COMPAT_15 # NetBSD 1.5,
#options COMPAT_16 # NetBSD 1.6,
#options COMPAT_20 # NetBSD 2.0,
options COMPAT_30 # NetBSD 3.0,
options COMPAT_40 # NetBSD 4.0,
options COMPAT_50 # NetBSD 5.0,
options COMPAT_60 # NetBSD 6.0, and
options COMPAT_70 # NetBSD 7.0 binary compatibility.
#options TCP_COMPAT_42 # 4.2BSD TCP/IP bug compat. Not recommended.
#options COMPAT_BSDPTY # /dev/[pt]ty?? ptys.
# Shared memory options
options SYSVMSG # System V-like message queues
options SYSVSEM # System V-like semaphores
options SYSVSHM # System V-like memory sharing
# Device options
#options MEMORY_DISK_HOOKS # boottime setup of ramdisk
#options MEMORY_DISK_ROOT_SIZE=8192 # Size in blocks
#options MEMORY_DISK_DYNAMIC
#options MINIROOTSIZE=1000 # Size in blocks
#options MEMORY_DISK_IS_ROOT # use memory disk as root
# Wedge support
options DKWEDGE_AUTODISCOVER # Automatically add dk(4) instances
options DKWEDGE_METHOD_GPT # Supports GPT partitions as wedges
# Miscellaneous kernel options
options KTRACE # system call tracing, a la ktrace(1)
#options SCSIVERBOSE # Verbose SCSI errors
#options MIIVERBOSE # Verbose MII autoconfuration messages
#options DDB_KEYCODE=0x40
#options USERCONF # userconf(4) support
#options PIPE_SOCKETPAIR # smaller, but slower pipe(2)
# Development and Debugging options
#options PERFCTRS # performance counters
options DIAGNOSTIC # internal consistency checks
options DEBUG
options LOCKDEBUG
#options PMAP_DEBUG # Enable pmap_debug_level code
#options IPKDB # remote kernel debugging
options VERBOSE_INIT_ARM # verbose bootstraping messages
options DDB # in-kernel debugger
options DDB_ONPANIC=1
options DDB_HISTORY_SIZE=100 # Enable history editing in DDB
#options KGDB
makeoptions DEBUG="-g" # compile full symbol table
makeoptions COPY_SYMTAB=1
## USB Debugging options
options USB_DEBUG
options EHCI_DEBUG
options OHCI_DEBUG
options UHUB_DEBUG
options USBVERBOSE
# Valid options for BOOT_ARGS:
# single Boot to single user only
# kdb Give control to kernel debugger
# ask Ask for file name to reboot from
# memorydisk=<n> Set memorydisk size to <n> KB
# quiet Show aprint_naive output
# verbose Show aprint_normal and aprint_verbose output
#options BOOT_ARGS="\"\""
options BOOT_ARGS="\"verbose\""
config netbsd root on ? type ?
# The main bus device
mainbus0 at root
# The boot cpu and secondary CPUs
cpu0 at mainbus?
#cpu? at mainbus? # Multiprocessor
# A9 core devices
armperiph0 at mainbus?
armgic0 at armperiph? # Interrupt Controller
armgtmr0 at armperiph? # Generic Timer
# Exynos SoC
exyo0 at mainbus?
# Integrated Samsung UARTs
#sscom* at exyo0 port ? # UART ?
sscom2 at exyo0 port 2 # UART2
# Exynos Watchdog Timer
#exyowdt0 at exyo0 # watchdog
# GPIO
exyogpio0 at exyo0
gpio* at exyogpio?
# On-board USB
exyousb* at exyo0
ohci* at exyousb?
ehci* at exyousb?
usb* at ohci?
usb* at ehci?
# Network phy for the LAN9730
ukphy* at mii? phy ? # generic unknown PHYs
# I2C devices
exyoiic0 at exyo0
iic* at exyoiic?
# SATA
#ahcisata* at exyno0
#atabus* at ata?
#wd* at atabus? drive ?
# serial console connectivity
options SSCOM2CONSOLE, CONSPEED=115200
# include all USB devices
include "dev/usb/usbdevices.config"
midi* at midibus?
# Pseudo-Devices
# disk/mass storage pseudo-devices
#pseudo-device md # memory disk device (ramdisk)
#pseudo-device vnd # disk-like interface to files
#pseudo-device fss # file system snapshot device
#pseudo-device putter # for puffs and pud
pseudo-device drvctl # driver control
# network pseudo-devices
pseudo-device bpfilter # Berkeley packet filter
pseudo-device loop # network loopback
#pseudo-device kttcp # network loopback
# miscellaneous pseudo-devices
pseudo-device pty # pseudo-terminals
#options RND_COM
#pseudo-device clockctl # user control of clock subsystem
pseudo-device ksyms # /dev/ksyms
#pseudo-device lockstat # lock profiling

View File

@ -1,11 +0,0 @@
# $NetBSD: ODROID-XU_INSTALL,v 1.1 2014/09/26 15:33:58 reinoud Exp $
#
# ODROID_INSTALL -- ODROID kernel with installation-sized
# ramdisk
#
include "arch/evbarm/conf/ODROID-XU"
include "arch/evbarm/conf/INSTALL"
options BOOTHOWTO=RB_SINGLE
no makeoptions DEBUG

131
sys/arch/evbarm/conf/SUNXI Normal file
View File

@ -0,0 +1,131 @@
#
# $NetBSD: SUNXI,v 1.17.4.2 2017/07/18 19:13:09 snj Exp $
#
# Allwinner sunxi family
#
include "arch/evbarm/conf/std.sunxi"
include "arch/evbarm/conf/GENERIC.common"
makeoptions DTS="
sun6i-a31-app4-evb1.dts
sun6i-a31-colombus.dts
sun6i-a31-hummingbird.dts
sun6i-a31-i7.dts
sun6i-a31-m9.dts
sun6i-a31-mele-a1000g-quad.dts
sun8i-h3-bananapi-m2-plus.dts
sun8i-h3-beelink-x2.dts
sun8i-h3-nanopi-m1.dts
sun8i-h3-nanopi-neo.dts
sun8i-h3-orangepi-2.dts
sun8i-h3-orangepi-lite.dts
sun8i-h3-orangepi-pc-plus.dts
sun8i-h3-orangepi-pc.dts
sun8i-h3-orangepi-plus.dts
sun8i-h3-orangepi-plus2e.dts
"
options CPU_CORTEXA7
options SOC_SUN6I_A31
options SOC_SUN8I_A83T
options SOC_SUN8I_H3
options MULTIPROCESSOR
pseudo-device openfirm # /dev/openfirm
#options DIAGNOSTIC # internal consistency checks
#options DEBUG
#options LOCKDEBUG
#options PMAP_DEBUG # Enable pmap_debug_level code
#options IPKDB # remote kernel debugging
#options VERBOSE_INIT_ARM # verbose bootstrapping messages
# CONSADDR is required for early init messages from VERBOSE_INIT_ARM.
#options CONSADDR=0x01c28000
makeoptions DEBUG="-g" # compile full symbol table
makeoptions COPY_SYMTAB=1
config netbsd root on ? type ?
# Device tree support
armfdt0 at root
fdt* at fdtbus?
# CPUs
cpus* at fdt? pass 0
cpu* at cpus?
# Power state coordination interface
psci* at fdt?
# Clock and reset controllers
sun6ia31ccu* at fdt? pass 4 # A31 CCU
sun8ia83tccu* at fdt? pass 4 # A83T CCU
sun8ih3ccu* at fdt? pass 4 # H3 CCU
sunxiresets* at fdt? pass 1 # Misc. clock resets
sunxigates* at fdt? pass 1 # Misc. clock gates
fclock* at fdt? pass 1
ffclock* at fdt? pass 1
fregulator* at fdt? pass 4
gpiokeys* at fdt?
gpioleds* at fdt?
# Timer
gtmr* at fdt? pass 1 # ARM Generic Timer
armgtmr0 at gtmr?
# Interrupt controller
gic* at fdt? pass 1 # GIC
armgic0 at gic?
# Memory controller
# DMA controller
# Clock and Reset controller
# GPIO controller
sunxigpio* at fdt? pass 2 # GPIO
gpio* at gpiobus?
# Ethernet
sunxiemac* at fdt? # Allwinner Gigabit Ethernet
rgephy* at mii? phy ?
ukphy* at mii? phy ?
# UART
com* at fdt? # UART
options COM_AWIN # XXX this should be a driver flag
# I2C
sunxitwi* at fdt? # TWI
options GTTWSI_ALLWINNER # XXX this should be a driver flag
sunxirsb* at fdt? # P2WI/RSB
iic* at i2cbus?
# RTC
sunxirtc* at fdt? # RTC
# SDMMC
sunximmc* at fdt? # SDMMC
sdmmc* at sunximmc?
ld0 at sdmmc0
ld1 at sdmmc1
ld2 at sdmmc2
ld3 at sdmmc3
ld* at sdmmc?
# USB 2.0
sunxiusbphy* at fdt? pass 9 # USB PHY
ehci* at fdt? # EHCI
ohci* at fdt? # OHCI
usb* at ehci?
usb* at ohci?
include "dev/usb/usbdevices.config"
midi* at midibus?
cinclude "arch/evbarm/conf/SUNXI.local"

View File

@ -1,5 +1,5 @@
#
# $NetBSD: TEGRA,v 1.23 2017/06/02 00:09:56 jmcneill Exp $
# $NetBSD: TEGRA,v 1.23.2.1 2017/07/18 19:13:09 snj Exp $
#
# NVIDIA Tegra K1 (T124)
#
@ -7,6 +7,14 @@
include "arch/evbarm/conf/std.tegra"
include "arch/evbarm/conf/GENERIC.common"
makeoptions DTS="
tegra124-apalis-eval.dts
tegra124-jetson-tk1.dts
tegra124-nyan-big.dts
tegra124-nyan-blaze.dts
tegra124-venice2.dts
"
options CPU_CORTEXA15
options SOC_TEGRA124
options MULTIPROCESSOR

View File

@ -1,5 +1,5 @@
#
# $NetBSD: VEXPRESS_A15,v 1.12.2.3 2017/06/10 05:57:08 snj Exp $
# $NetBSD: VEXPRESS_A15,v 1.12.2.4 2017/07/18 19:13:09 snj Exp $
#
# ARM Versatile Express A15
#
@ -7,6 +7,8 @@
include "arch/evbarm/conf/std.vexpress"
include "arch/evbarm/conf/GENERIC.common"
makeoptions DTS="vexpress-v2p-ca15-tc1.dts"
options CPU_CORTEXA15
options MULTIPROCESSOR

View File

@ -1,4 +1,4 @@
# $NetBSD: files.evbarm,v 1.25 2014/12/04 21:15:48 joerg Exp $
# $NetBSD: files.evbarm,v 1.25.10.1 2017/07/18 19:13:09 snj Exp $
#
# First try for arm-specific configuration info
#
@ -48,4 +48,9 @@ defflag opt_plcom.h PLCOM_DEBUG
device plcom { }: tty
file arch/evbarm/dev/plcom.c plcom needs-flag
#
# Maximum number of memory ranges
#
defparam opt_machdep.h DRAM_BLOCKS
include "arch/arm/conf/majors.arm32"

View File

@ -1,18 +1,8 @@
# $NetBSD: files.exynos,v 1.2 2015/12/14 22:06:57 marty Exp $
# $NetBSD: files.exynos,v 1.2.12.1 2017/07/18 19:13:09 snj Exp $
#
# EXYNOS 5422 board configuration info
# EXYNOS board configuration info
#
file arch/evbarm/exynos/exynos_machdep.c
include "arch/evbarm/conf/files.fdt"
# Kernel boot arguments
defparam opt_machdep.h BOOT_ARGS
# FDT
include "dev/ofw/files.ofw"
include "dev/fdt/files.fdt"
include "arch/arm/fdt/files.fdt"
# Pull in Exynos SoC default
include "arch/arm/samsung/files.exynos"
include "arch/arm/samsung/files.exynos"

View File

@ -0,0 +1,8 @@
# $NetBSD: files.sunxi,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $
#
# Allwinner sunxi configuration info
#
include "arch/evbarm/conf/files.fdt"
include "arch/arm/sunxi/files.sunxi"

View File

@ -0,0 +1,32 @@
# $NetBSD: mk.sunxi,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $
SYSTEM_FIRST_OBJ= sunxi_start.o
SYSTEM_FIRST_SFILE= ${THISARM}/sunxi/sunxi_start.S
AFLAGS.sunxi_start.S+= -Wa,-march=armv7-a+virt
AFLAGS.psci_arm.S+= -Wa,-march=armv7-a+sec+virt
GENASSYM_EXTRAS+= ${THISARM}/sunxi/genassym.cf
_OSRELEASE!= ${HOST_SH} $S/conf/osrelease.sh
MKUBOOTIMAGEARGS= -A arm -T kernel -O linux
MKUBOOTIMAGEARGS+= -a $(KERNEL_BASE_PHYS) -e $(KERNEL_BASE_PHYS)
MKUBOOTIMAGEARGS+= -n "NetBSD/$(BOARDTYPE) ${_OSRELEASE}"
MKUBOOTIMAGEARGS_NONE= ${MKUBOOTIMAGEARGS} -C none
MKUBOOTIMAGEARGS_GZ= ${MKUBOOTIMAGEARGS} -C gz
SYSTEM_LD_TAIL_EXTRA+=; \
echo ${OBJCOPY} -S -O binary $@ $@.bin; \
${OBJCOPY} -S -O binary $@ $@.bin; \
echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \
${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \
echo ${TOOL_GZIP} -c $@.bin > $@.bin.gz; \
${TOOL_GZIP} -c $@.bin > $@.bin.gz; \
echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_GZ} $@.bin.gz $@.gz.ub; \
${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_GZ} $@.bin.gz $@.gz.ub
EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin@}
EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.ub@}
EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin.gz@}
EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.gz.ub@}

View File

@ -1,35 +1,36 @@
# $NetBSD: std.exynos,v 1.1 2015/12/06 00:31:24 marty Exp $
# $NetBSD: std.exynos,v 1.1.12.1 2017/07/18 19:13:09 snj Exp $
#
# standard NetBSD/evbarm for EXYNOS options
machine evbarm arm
include "arch/evbarm/conf/std.evbarm"
# Pull in EXYNOS config definitions
include "arch/evbarm/conf/files.exynos"
include "arch/evbarm/conf/files.exynos"
makeoptions CPUFLAGS="-march=armv7-a -mfpu=neon"
makeoptions CPUFLAGS="-march=armv7-a -mfpu=neon"
# To support easy transit to ../arch/arm/arm32
options MODULAR
options MODULAR_DEFAULT_AUTOLOAD
options ARM_HAS_VBAR
options CORTEX_PMC
options __HAVE_CPU_COUNTER
options __HAVE_FAST_SOFTINTS # should be in types.h
#options __HAVE_MM_MD_DIRECT_MAPPED_PHYS
options TPIDRPRW_IS_CURCPU
options KERNEL_BASE_EXT=0x80000000
options FPU_VFP
# All shipped Samsung SoC's that are not Samsung products have this
options ARM_TRUSTZONE_FIRMWARE
options __NO_FIQ
makeoptions KERNEL_BASE_PHYS="0x80000000"
options FDT # Flattened Device Tree support
options DRAM_BLOCKS=256
options MODULAR
options MODULAR_DEFAULT_AUTOLOAD
options __HAVE_CPU_COUNTER
options __HAVE_FAST_SOFTINTS # should be in types.h
options ARM_HAS_VBAR
#options __HAVE_MM_MD_DIRECT_MAPPED_PHYS
#options PMAP_NEED_ALLOC_POOLPAGE
options TPIDRPRW_IS_CURCPU
options KERNEL_BASE_EXT=0x80000000
options FPU_VFP
options PCI_NETBSD_CONFIGURE
options __HAVE_PCI_CONF_HOOK
options __BUS_SPACE_HAS_STREAM_METHODS
makeoptions KERNEL_BASE_PHYS="0x40000000"
makeoptions KERNEL_BASE_VIRT="0x80000000"
makeoptions BOARDTYPE="exynos"
makeoptions BOARDMKFRAG="${THISARM}/conf/mk.exynos"
options ARM_INTR_IMPL="<arch/arm/samsung/exynos_intr.h>"
options ARM_INTR_IMPL="<arch/arm/fdt/fdt_intr.h>"
options ARM_GENERIC_TODR

View File

@ -0,0 +1,36 @@
# $NetBSD: std.sunxi,v 1.3.4.2 2017/07/18 19:13:09 snj Exp $
#
machine evbarm arm
include "arch/evbarm/conf/std.evbarm"
include "arch/evbarm/conf/files.sunxi"
options FDT # Flattened Device Tree support
options DRAM_BLOCKS=256
options MODULAR
options MODULAR_DEFAULT_AUTOLOAD
options __HAVE_CPU_COUNTER
options __HAVE_FAST_SOFTINTS # should be in types.h
options __HAVE_CPU_UAREA_ALLOC_IDLELWP
options ARM_HAS_VBAR
#options __HAVE_MM_MD_DIRECT_MAPPED_PHYS
#options PMAP_NEED_ALLOC_POOLPAGE
options TPIDRPRW_IS_CURCPU
options KERNEL_BASE_EXT=0x80000000
options FPU_VFP
options __BUS_SPACE_HAS_STREAM_METHODS
makeoptions KERNEL_BASE_PHYS="0x40008000"
makeoptions KERNEL_BASE_VIRT="0x80008000"
makeoptions BOARDTYPE="sunxi"
makeoptions BOARDMKFRAG="${THISARM}/conf/mk.sunxi"
makeoptions CPUFLAGS="-march=armv7-a -mfpu=neon"
options ARM_INTR_IMPL="<arch/arm/fdt/fdt_intr.h>"
options ARM_GENERIC_TODR
# initrd support
options MEMORY_DISK_HOOKS
options MEMORY_DISK_DYNAMIC
pseudo-device md

View File

@ -1,4 +1,4 @@
# $NetBSD: std.tegra,v 1.13.2.1 2017/07/05 19:57:46 snj Exp $
# $NetBSD: std.tegra,v 1.13.2.2 2017/07/18 19:13:09 snj Exp $
#
machine evbarm arm
@ -7,6 +7,7 @@ include "arch/evbarm/conf/std.evbarm"
include "arch/evbarm/conf/files.tegra"
options FDT # Flattened Device Tree support
options DRAM_BLOCKS=256
options MODULAR
options MODULAR_DEFAULT_AUTOLOAD
options __HAVE_CPU_COUNTER

View File

@ -1,4 +1,4 @@
# $NetBSD: std.vexpress,v 1.4 2017/06/02 15:22:47 jmcneill Exp $
# $NetBSD: std.vexpress,v 1.4.2.1 2017/07/18 19:13:09 snj Exp $
#
# standard NetBSD/evbarm for VEXPRESS options
@ -9,6 +9,7 @@ include "arch/evbarm/conf/std.evbarm"
include "arch/evbarm/conf/files.vexpress"
options FDT # Flattened Device Tree support
options DRAM_BLOCKS=256
options MODULAR
options MODULAR_DEFAULT_AUTOLOAD
options ARM_HAS_VBAR

View File

@ -1,567 +0,0 @@
/* $NetBSD: exynos_machdep.c,v 1.7 2015/12/21 04:58:50 marty Exp $ */
/*
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Reinoud Zandijk.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exynos_machdep.c,v 1.7 2015/12/21 04:58:50 marty Exp $");
#include "opt_evbarm_boardtype.h"
#include "opt_exynos.h"
#include "opt_machdep.h"
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_ipkdb.h"
#include "opt_md.h"
#include "opt_sscom.h"
#include "opt_arm_debug.h"
#include "ukbd.h"
#include "arml2cc.h" // RPZ why is it not called opt_l2cc.h?
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <sys/exec.h>
#include <sys/kernel.h>
#include <sys/ksyms.h>
#include <sys/msgbuf.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/termios.h>
#include <sys/gpio.h>
#include <uvm/uvm_extern.h>
#include <sys/conf.h>
#include <dev/cons.h>
#include <dev/md.h>
#include <machine/db_machdep.h>
#include <ddb/db_sym.h>
#include <ddb/db_extern.h>
#ifdef KGDB
#include <sys/kgdb.h>
#endif
#include <machine/bootconfig.h>
#include <arm/armreg.h>
#include <arm/undefined.h>
#include <arm/cortex/pl310_var.h>
#include <arm/arm32/machdep.h>
#include <arm/mainbus/mainbus.h>
#include <arm/samsung/exynos5_reg.h>
#include <arm/samsung/exynos_var.h>
#include <evbarm/include/autoconf.h>
#include <evbarm/exynos/platform.h>
#include <dev/i2c/i2cvar.h>
#include <dev/i2c/ddcreg.h>
#include <dev/usb/ukbdvar.h>
#include <net/if_ether.h>
/* serial console stuff */
#include "sscom.h"
#include "opt_sscom.h"
#include <arm/samsung/sscom_var.h>
#include <arm/samsung/sscom_reg.h>
/* so we can load the device tree. NOTE: This requires the kernel to be
* made into a linux (not netbsd) uboot image.
*/
#include <libfdt.h>
#include <dev/fdt/fdtvar.h>
#define FDT_BUF_SIZE (128*1024)
static uint8_t fdt_data[FDT_BUF_SIZE];
extern const int num_exynos_uarts_entries;
extern const struct sscom_uart_info exynos_uarts[];
#ifndef CONSPEED
#define CONSPEED 115200
#endif /* CONSPEED */
#ifndef CONMODE
#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB | HUPCL)) | CS8) /* 8N1 */
#endif /* CONMODE */
static const int conspeed = CONSPEED;
static const int conmode = CONMODE;
/*
* uboot passes 4 arguments to us.
*
* arg0 arg1 arg2 arg3 : the `bootargs' environment variable from the uboot
* context (in PA!)
*
* Note that the storage has to be in .data and not in .bss. On kernel start
* the .bss is cleared and this information would get lost.
*/
uintptr_t uboot_args[4] = { 0 };
/*
* argument and boot configure storage
*/
BootConfig bootconfig; /* for pmap's sake */
char bootargs[MAX_BOOT_STRING] = ""; /* copied string from uboot */
char *boot_args = NULL; /* MI bootargs */
char *boot_file = NULL; /* MI bootfile */
uint8_t uboot_enaddr[ETHER_ADDR_LEN] = {};
void
odroid_device_register(device_t self, void *aux);
/*
* kernel start and end from the linker
*/
extern char KERNEL_BASE_phys[]; /* physical start of kernel */
extern char _end[]; /* physical end of kernel */
#define KERNEL_BASE_PHYS ((paddr_t)KERNEL_BASE_phys)
#define EXYNOS_IOPHYSTOVIRT(a) \
((vaddr_t)(((a) - EXYNOS_CORE_PBASE) + EXYNOS_CORE_VBASE))
static void exynos_reset(void);
static void exynos_powerdown(void);
/* XXX we have no framebuffer implementation yet so com is console XXX */
int use_fb_console = false;
/* prototypes */
void consinit(void);
#ifdef KGDB
static void kgdb_port_init(void);
#endif
static void exynos_extract_mac_adress(void);
void exynos_device_register(device_t self, void *aux);
void exynos_device_register_post_config(device_t self, void *aux);
/*
* Our static device mappings at fixed virtual addresses so we can use them
* while booting the kernel.
*
* Map the extents segment-aligned and segment-rounded in size to avoid L2
* page tables
*/
#define _A(a) ((a) & ~L1_S_OFFSET)
#define _S(s) (((s) + L1_S_SIZE - 1) & (~(L1_S_SIZE-1)))
static const struct pmap_devmap e5_devmap[] = {
{
/* map in core IO space */
.pd_va = _A(EXYNOS_CORE_VBASE),
.pd_pa = _A(EXYNOS_CORE_PBASE),
.pd_size = _S(EXYNOS5_CORE_SIZE),
.pd_prot = VM_PROT_READ | VM_PROT_WRITE,
.pd_cache = PTE_NOCACHE
},
{
/* map in audiocore IO space */
.pd_va = _A(EXYNOS5_AUDIOCORE_VBASE),
.pd_pa = _A(EXYNOS5_AUDIOCORE_PBASE),
.pd_size = _S(EXYNOS5_AUDIOCORE_SIZE),
.pd_prot = VM_PROT_READ | VM_PROT_WRITE,
.pd_cache = PTE_NOCACHE
},
{0}
};
#undef _A
#undef _S
#ifdef PMAP_NEED_ALLOC_POOLPAGE
static struct boot_physmem bp_highgig = {
.bp_pages = (KERNEL_VM_BASE - KERNEL_BASE) / NBPG,
.bp_freelist = VM_FREELIST_ISADMA,
.bp_flags = 0,
};
#endif
static struct gpio_pin_entry {
const char *pin_name;
const char *pin_user;
} gpio_pin_entries[] = {
/* mux@13400000 (muxa) */
{ "gpx3-7", "hdmi-hpd-irq"},
{ "gpx3-6", "hdmi_cec" },
{ "gpx0-7", "dp_hpd_gpio" },
{ "gpx0-4", "pmic-irq" },
{ "gpx3-2", "audio-irq" },
{ "gpx3-4", "b-sess1-irq" },
{ "gpx3-5", "b-sess0-irq" },
{ "gpx1-1", "id2-irq" },
/* mux@134100000 (muxb) */
{ "gpc0-0", "sd0-clk" },
{ "gpc0-1", "sd0-cmd" },
{ "gpc0-7", "sd0-rdqs" },
{ "gpd1-3", "sd0-qrdy" },
{ "gpc0-3", "sd0-bus-width1" },
{ "gpc0-3", "sd0-bus-width4-bit1" },
{ "gpc0-4", "sd0-bus-width4-bit2" },
{ "gpc0-5", "sd0-bus-width4-bit3" },
{ "gpc0-6", "sd0-bus-width4-bit4" },
{ "gpc1-0", "sd1-clk" },
{ "gpc1-1", "sd1-cmd" },
{ "gpc1-3", "sd1-bus-width1" },
{ "gpc1-3", "sd1-bus-width4-bit1" },
{ "gpc1-4", "sd1-bus-width4-bit2" },
{ "gpc1-5", "sd1-bus-width4-bit3" },
{ "gpc1-6", "sd1-bus-width4-bit4" },
/* TODO: muxc and muxd as needed */
{ 0, 0}
};
#ifdef VERBOSE_INIT_ARM
extern void exynos_putchar(int);
static void
exynos_putstr(const char *s)
{
for (const char *p = s; *p; p++) {
exynos_putchar(*p);
}
}
static void
exynos_printn(u_int n, int base)
{
char *p, buf[(sizeof(u_int) * NBBY / 3) + 1 + 2 /* ALT + SIGN */];
p = buf;
do {
*p++ = hexdigits[n % base];
} while (n /= base);
do {
exynos_putchar(*--p);
} while (p > buf);
}
#define DPRINTF(...) printf(__VA_ARGS__)
#define DPRINT(x) exynos_putstr(x)
#define DPRINTN(x,b) exynos_printn((x), (b))
#else
#define DPRINTF(...)
#define DPRINT(x)
#define DPRINTN(x,b)
#endif
extern void cortex_mpstart(void);
/*
* void init_gpio_dictionary(...)
*
* Setup the dictionary of gpio pin names for the drivers to use
*/
static void init_gpio_dictionary(struct gpio_pin_entry *pins,
prop_dictionary_t dict)
{
while (pins->pin_name) {
prop_dictionary_set_cstring(dict, pins->pin_user,
pins->pin_name);
pins++;
}
}
/*
* u_int initarm(...)
*
* Our entry point from the assembly before main() is called.
* - take a copy of the config we got from uboot
* - init the physical console
* - setting up page tables for the kernel
*/
u_int
initarm(void *arg)
{
const struct pmap_devmap const *devmap;
bus_addr_t rambase;
psize_t ram_size;
DPRINT("initarm:");
DPRINT(" mpstart<0x");
DPRINTN((uint32_t)cortex_mpstart, 16);
DPRINT(">");
/* allocate/map our basic memory mapping */
switch (EXYNOS_PRODUCT_FAMILY(exynos_soc_id)) {
#if defined(EXYNOS5)
case EXYNOS5_PRODUCT_FAMILY:
devmap = e5_devmap;
rambase = EXYNOS5_SDRAM_PBASE;
break;
#endif
default:
/* Won't work, but... */
panic("Unknown product family %llx",
EXYNOS_PRODUCT_FAMILY(exynos_soc_id));
}
pmap_devmap_register(devmap);
/* bootstrap soc. uart_address is determined in exynos_start */
paddr_t uart_address = armreg_tpidruro_read();
exynos_bootstrap(EXYNOS_CORE_VBASE, EXYNOS_IOPHYSTOVIRT(uart_address));
/* set up CPU / MMU / TLB functions */
if (set_cpufuncs())
panic("cpu not recognized!");
/* get normal console working */
consinit();
#ifdef KGDB
kgdb_port_init();
#endif
#ifdef VERBOSE_INIT_ARM
printf("\nuboot arg = %#"PRIxPTR", %#"PRIxPTR", %#"PRIxPTR", %#"PRIxPTR"\n",
uboot_args[0], uboot_args[1], uboot_args[2], uboot_args[3]);
printf("Exynos SoC ID %08x\n", exynos_soc_id);
printf("initarm: cbar=%#x\n", armreg_cbar_read());
#endif
/* determine cpu0 clock rate */
exynos_clocks_bootstrap();
#ifdef VERBOSE_INIT_ARM
printf("CPU0 now running on %"PRIu64" Mhz\n", exynos_get_cpufreq()/(1000*1000));
#endif
cpu_reset_address = exynos_reset;
cpu_powerdown_address = exynos_powerdown;
#ifdef VERBOSE_INIT_ARM
printf("\nNetBSD/evbarm (Exynnos 5422) booting ...\n");
#endif
#ifdef BOOT_ARGS
char mi_bootargs[] = BOOT_ARGS;
parse_mi_bootargs(mi_bootargs);
#endif
boot_args = bootargs;
parse_mi_bootargs(boot_args);
exynos_extract_mac_adress();
/* Don't map the DMA reserved region */
// ram_size = (psize_t) 0xC0000000 - 0x40000000;
ram_size = (psize_t) 0xb0000000 - 0x40000000;
#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
const bool mapallmem_p = true;
#ifndef PMAP_NEED_ALLOC_POOLPAGE
if (ram_size > KERNEL_VM_BASE - KERNEL_BASE) {
printf("%s: dropping RAM size from %luMB to %uMB\n",
__func__, (unsigned long) (ram_size >> 20),
(KERNEL_VM_BASE - KERNEL_BASE) >> 20);
ram_size = KERNEL_VM_BASE - KERNEL_BASE;
}
#endif
#else
const bool mapallmem_p = false;
#endif
/* Load the dtb */
const uint8_t *fdt_addr_r = (const uint8_t *)uboot_args[2];
printf("fdt addr 0x%08x\n", (uint)fdt_addr_r);
int error = fdt_check_header(fdt_addr_r);
printf("fdt check header returns %d\n", error);
if (error == 0) {
error = fdt_move(fdt_addr_r, fdt_data, sizeof(fdt_data));
printf("fdt move returns %d\n", error);
if (error != 0) {
panic("fdt_move failed: %s", fdt_strerror(error));
}
fdtbus_set_data(fdt_data);
} else {
panic("fdt_check_header failed: %s", fdt_strerror(error));
}
/* Fake bootconfig structure for the benefit of pmap.c. */
bootconfig.dramblocks = 1;
bootconfig.dram[0].address = rambase;
bootconfig.dram[0].pages = ram_size / PAGE_SIZE;
KASSERT((armreg_pfr1_read() & ARM_PFR1_SEC_MASK) != 0);
arm32_bootmem_init(bootconfig.dram[0].address, ram_size,
KERNEL_BASE_PHYS);
arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0, devmap,
mapallmem_p);
/* we've a specific device_register routine */
evbarm_device_register = odroid_device_register;
// evbarm_device_register_post_config = exynos_device_register_post_config;
/*
* If we couldn't map all of memory via TTBR1, limit the memory the
* kernel can allocate from to be from the highest available 1GB.
*/
#ifdef PMAP_NEED_ALLOC_POOLPAGE
if (atop(ram_size) > bp_highgig.bp_pages) {
arm_poolpage_vmfreelist = bp_highgig.bp_freelist;
return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE,
&bp_highgig, 1);
}
#endif
return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
}
void
consinit(void)
{
static bool consinit_called;
if (consinit_called)
return;
consinit_called = true;
#if NSSCOM > 0
bus_space_tag_t bst = &armv7_generic_bs_tag;
bus_addr_t iobase = armreg_tpidruro_read();
bus_space_handle_t bsh = EXYNOS_IOPHYSTOVIRT(iobase);
u_int i;
/*
* No need to guess at the UART frequency since we can calculate it.
*/
uint32_t freq = conspeed
* (16 * (bus_space_read_4(bst, bsh, SSCOM_UBRDIV) + 1)
+ bus_space_read_4(bst, bsh, SSCOM_UFRACVAL));
freq = (freq + conspeed / 2) / 1000;
freq *= 1000;
/* go through all entries */
for (i = 0; i < num_exynos_uarts_entries; i++) {
/* attach console */
if (exynos_uarts[i].iobase + EXYNOS_CORE_PBASE == iobase)
break;
}
KASSERT(i < num_exynos_uarts_entries);
printf("%s: attaching console @ %#"PRIxPTR" (%u HZ, %u bps)\n",
__func__, iobase, freq, conspeed);
if (sscom_cnattach(bst, exynos_core_bsh, &exynos_uarts[i],
conspeed, freq, conmode))
panic("Serial console can not be initialized");
#ifdef VERBOSE_INIT_ARM
printf("Console initialized\n");
#endif
#else
#error only serial console is supported
#if NUKBD > 0
/* allow USB keyboards to become console */
ukbd_cnattach();
#endif /* NUKBD */
#endif
}
/* extract ethernet mac address from bootargs */
static void
exynos_extract_mac_adress(void)
{
char *str, *ptr;
int i, v1, v2, val;
#define EXPECT_COLON() {\
v1 = *ptr++; \
if (v1 != ':') break; \
}
#define EXPECT_HEX(v) {\
(v) = (v) >= '0' && (v) <= '9'? (v) - '0' : \
(v) >= 'a' && (v) <= 'f'? (v) - 'a' + 10 : \
(v) >= 'A' && (v) <= 'F'? (v) - 'A' + 10 : -1; \
if ((v) < 0) break; \
}
#define EXPECT_2HEX(val) {\
v1 = *ptr++; EXPECT_HEX(v1); \
v2 = *ptr++; EXPECT_HEX(v2); \
val = (v1 << 4) | v2; \
}
if (get_bootconf_option(boot_args, "ethaddr",
BOOTOPT_TYPE_STRING, &str)) {
for (i = 0, ptr = str; i < sizeof(uboot_enaddr); i++) {
if (i)
EXPECT_COLON();
EXPECT_2HEX(val);
uboot_enaddr[i] = val;
}
if (i != sizeof(uboot_enaddr)) {
printf( "Ignoring invalid MAC address '%s' passed "
"as boot paramter `ethaddr'\n", str);
memset((char *) uboot_enaddr, 0, sizeof(uboot_enaddr));
}
}
#undef EXPECT_2HEX
#undef EXPECT_HEX
#undef EXPECT_COLON
}
void
odroid_device_register(device_t self, void *aux)
{
prop_dictionary_t dict = device_properties(self);
exynos_device_register(self, aux);
if (device_is_a(self, "exyogpio")) {
init_gpio_dictionary(gpio_pin_entries, dict);
} else if (device_is_a(self, "exyowdt")) {
prop_dictionary_set_uint32(dict, "frequency",
EXYNOS_F_IN_FREQ);
}
}
/*
* Exynos specific tweaks
*/
/*
* The external USB devices are clocked trough the DEBUG clkout
* XXX is this Odroid specific? XXX
*/
void
exynos_init_clkout_for_usb(void)
{
/* Select XUSBXTI as source for CLKOUT */
bus_space_write_4(&armv7_generic_bs_tag, exynos_pmu_bsh,
EXYNOS_PMU_DEBUG_CLKOUT, 0x1000);
}
static void
exynos_reset(void)
{
}
static void
exynos_powerdown(void)
{
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: exynos_start.S,v 1.3 2015/12/17 08:03:06 skrll Exp $ */
/* $NetBSD: exynos_start.S,v 1.3.12.1 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -45,7 +45,7 @@
#include <evbarm/exynos/platform.h>
RCSID("$NetBSD: exynos_start.S,v 1.3 2015/12/17 08:03:06 skrll Exp $")
RCSID("$NetBSD: exynos_start.S,v 1.3.12.1 2017/07/18 19:13:09 snj Exp $")
#if defined(VERBOSE_INIT_ARM)
@ -68,7 +68,7 @@ RCSID("$NetBSD: exynos_start.S,v 1.3 2015/12/17 08:03:06 skrll Exp $")
#define TEMP_L1_TABLE (KERNEL_BASE - KERNEL_BASE_VOFFSET + INIT_MEMSIZE * L1_S_SIZE - L1_TABLE_SIZE)
#define MD_CPU_HATCH _C_LABEL(gtmr_init_cpu_clock)
#define MD_CPU_HATCH _C_LABEL(arm_fdt_cpu_hatch)
/*
* Kernel start routine for Exynos 5422 boards running on uboot firmware
@ -100,6 +100,18 @@ _C_LABEL(exynos_start):
#endif
stmia r4, {r0-r3} // Save the arguments
/* Add DTB PA (1MB) from r2 to MMU init table */
movw r3, #:lower16:(L1_S_SIZE - 1) /* align DTB PA to 1M */
movt r3, #:upper16:(L1_S_SIZE - 1)
bic r0, r2, r3
orr r0, r0, #1 /* 1MB mapping */
bic r1, r2, r3
movw r3, #:lower16:(L1_S_PROTO_armv7|L1_S_APv7_KRW|L1_S_CACHEABLE)
movt r3, #:upper16:(L1_S_PROTO_armv7|L1_S_APv7_KRW|L1_S_CACHEABLE)
orr r1, r1, r3
adrl r3, .Lmmu_init_table_dtb /* table entry addr */
stmia r3, {r0-r1} /* patch table entry */
/*
* For easy and early SoC / PoP dependency, retrieve the IDs
*/
@ -268,6 +280,11 @@ mmu_init_table:
EXYNOS_CORE_SIZE / L1_S_SIZE,
L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
/* Map DTB location in SDRAM, patched in later */
.Lmmu_init_table_dtb:
MMU_INIT(0, 0, 0, 0)
/* end of table */
MMU_INIT(0, 0, 0, 0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: platform.h,v 1.1 2015/12/06 00:33:44 marty Exp $ */
/* $NetBSD: platform.h,v 1.1.12.1 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -32,11 +32,7 @@
#ifndef _ARM_EXYNOS_PLATFORM_H
#define _ARM_EXYNOS_PLATFORM_H
/*
* Kernel VM space 16Mb behind KERNEL_BASE upto 0xeff00000
*/
#define KERNEL_VM_BASE 0xc0000000
#define KERNEL_VM_SIZE (EXYNOS_CORE_VBASE - KERNEL_VM_BASE)
#include <arch/evbarm/fdt/platform.h>
/*
* IO space

View File

@ -1,4 +1,4 @@
/* $NetBSD: fdt_machdep.c,v 1.4.2.2 2017/06/14 04:54:21 snj Exp $ */
/* $NetBSD: fdt_machdep.c,v 1.4.2.3 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.4.2.2 2017/06/14 04:54:21 snj Exp $");
__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.4.2.3 2017/07/18 19:13:09 snj Exp $");
#include "opt_machdep.h"
#include "opt_ddb.h"
@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.4.2.2 2017/06/14 04:54:21 snj Exp
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/termios.h>
#include <sys/extent.h>
#include <uvm/uvm_extern.h>
@ -70,6 +71,10 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.4.2.2 2017/06/14 04:54:21 snj Exp
#include <arm/fdt/arm_fdtvar.h>
#ifdef MEMORY_DISK_DYNAMIC
#include <dev/md.h>
#endif
#ifndef FDT_MAX_BOOT_STRING
#define FDT_MAX_BOOT_STRING 1024
#endif
@ -79,6 +84,11 @@ char bootargs[FDT_MAX_BOOT_STRING] = "";
char *boot_args = NULL;
u_int uboot_args[4] = { 0 }; /* filled in by xxx_start.S (not in bss) */
static char fdt_memory_ext_storage[EXTENT_FIXED_STORAGE_SIZE(DRAM_BLOCKS)];
static struct extent *fdt_memory_ext;
static uint64_t initrd_start, initrd_end;
#include <libfdt.h>
#include <dev/fdt/fdtvar.h>
#define FDT_BUF_SIZE (128*1024)
@ -167,6 +177,155 @@ fdt_get_memory(uint64_t *paddr, uint64_t *psize)
}
}
static void
fdt_add_reserved_memory_range(uint64_t addr, uint64_t size)
{
int error;
error = extent_free(fdt_memory_ext, addr, size, EX_NOWAIT);
if (error != 0)
printf("MEM ERROR: add %llx-%llx failed: %d\n",
addr, size, error);
DPRINTF("MEM: res %llx-%llx: %d\n", addr, size, error);
}
/*
* Exclude memory ranges from memory config from a /reserved-memory/ child
*/
static void
fdt_add_reserved_memory(int phandle, uint64_t max_addr)
{
uint64_t addr, size;
int index;
for (index = 0;
fdtbus_get_reg64(phandle, index, &addr, &size) == 0;
index++) {
if (addr >= max_addr)
continue;
if (addr + size > max_addr)
size = max_addr - addr;
fdt_add_reserved_memory_range(addr, size);
}
}
/*
* Define usable memory regions.
*/
static void
fdt_build_bootconfig(uint64_t mem_addr, uint64_t mem_size)
{
const int memory = OF_finddevice("/memory");
const uint64_t max_addr = mem_addr + mem_size;
BootConfig *bc = &bootconfig;
struct extent_region *er;
uint64_t addr, size;
int index, child, error;
fdt_memory_ext = extent_create("FDT Memory", mem_addr, max_addr,
fdt_memory_ext_storage, sizeof(fdt_memory_ext_storage), 0);
for (index = 0;
fdtbus_get_reg64(memory, index, &addr, &size) == 0;
index++) {
if (addr >= max_addr)
continue;
if (addr + size > max_addr)
size = max_addr - addr;
error = extent_alloc_region(fdt_memory_ext, addr, size,
EX_NOWAIT);
if (error != 0)
printf("MEM ERROR: add %llx-%llx failed: %d\n",
addr, size, error);
DPRINTF("MEM: add %llx-%llx\n", addr, size);
}
const int reserved = OF_finddevice("/reserved-memory");
if (reserved > 0)
for (child = OF_child(reserved); child; child = OF_peer(child))
fdt_add_reserved_memory(child, max_addr);
const uint64_t initrd_size = initrd_end - initrd_start;
if (initrd_size > 0)
fdt_add_reserved_memory_range(initrd_start, initrd_size);
DPRINTF("Usable memory:\n");
bc->dramblocks = 0;
LIST_FOREACH(er, &fdt_memory_ext->ex_regions, er_link) {
DPRINTF(" %lx - %lx\n", er->er_start, er->er_end);
bc->dram[bc->dramblocks].address = er->er_start;
bc->dram[bc->dramblocks].pages =
(er->er_end - er->er_start) / PAGE_SIZE;
bc->dramblocks++;
}
}
static void
fdt_probe_initrd(uint64_t *pstart, uint64_t *pend)
{
*pstart = *pend = 0;
#ifdef MEMORY_DISK_DYNAMIC
const int chosen = OF_finddevice("/chosen");
if (chosen < 0)
return;
int len;
const void *start_data = fdtbus_get_prop(chosen,
"linux,initrd-start", &len);
const void *end_data = fdtbus_get_prop(chosen,
"linux,initrd-end", NULL);
if (start_data == NULL || end_data == NULL)
return;
switch (len) {
case 4:
*pstart = be32dec(start_data);
*pend = be32dec(end_data);
break;
case 8:
*pstart = be64dec(start_data);
*pend = be64dec(end_data);
break;
default:
printf("Unsupported len %d for /chosen/initrd-start\n", len);
return;
}
#endif
}
static void
fdt_setup_initrd(void)
{
#ifdef MEMORY_DISK_DYNAMIC
const uint64_t initrd_size = initrd_end - initrd_start;
paddr_t startpa = trunc_page(initrd_start);
paddr_t endpa = round_page(initrd_end);
paddr_t pa;
vaddr_t va;
void *md_start;
if (initrd_size == 0)
return;
va = uvm_km_alloc(kernel_map, initrd_size, 0,
UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
if (va == 0) {
printf("Failed to allocate VA for initrd\n");
return;
}
md_start = (void *)va;
for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE)
pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE, 0);
pmap_update(pmap_kernel());
md_root_setconf(md_start, initrd_size);
#endif
}
u_int
initarm(void *arg)
{
@ -251,8 +410,8 @@ initarm(void *arg)
#if !defined(_LP64)
/* Cannot map memory above 4GB */
if (memory_addr + memory_size > 0x100000000)
memory_size = 0x100000000 - memory_addr;
if (memory_addr + memory_size >= 0x100000000)
memory_size = 0x100000000 - memory_addr - PAGE_SIZE;
#endif
ram_size = (bus_size_t)memory_size;
@ -271,10 +430,11 @@ initarm(void *arg)
const bool mapallmem_p = false;
#endif
/* Fake bootconfig structure for the benefit of pmap.c. */
bootconfig.dramblocks = 1;
bootconfig.dram[0].address = (bus_addr_t)memory_addr;
bootconfig.dram[0].pages = ram_size / PAGE_SIZE;
/* Parse ramdisk info */
fdt_probe_initrd(&initrd_start, &initrd_end);
/* Populate bootconfig structure for the benefit of pmap.c. */
fdt_build_bootconfig(memory_addr, memory_size);
arm32_bootmem_init(bootconfig.dram[0].address, ram_size,
KERNEL_BASE_PHYS);
@ -295,7 +455,6 @@ initarm(void *arg)
#endif
return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
}
static void
@ -360,6 +519,9 @@ fdt_device_register(device_t self, void *aux)
{
const struct arm_platform *plat = arm_fdt_platform();
if (device_is_a(self, "armfdt"))
fdt_setup_initrd();
if (plat && plat->device_register)
plat->device_register(self, aux);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: bootconfig.h,v 1.6 2006/02/06 14:03:22 hamajima Exp $ */
/* $NetBSD: bootconfig.h,v 1.6.152.1 2017/07/18 19:13:09 snj Exp $ */
/*
* Copyright (c) 1994 Mark Brinicombe.
@ -36,6 +36,8 @@
* SUCH DAMAGE.
*/
#include "opt_machdep.h"
#include <arm/bootconfig.h>
typedef struct _PhysMem {

View File

@ -0,0 +1,38 @@
# $NetBSD: genassym.cf,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $
#-
# Copyright (c) 2013 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Matt Thomas of 3am Software Foundry.
#
# 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
#
include <dev/ic/ns16550reg.h>
include <dev/ic/comreg.h>
define LSR_TXRDY LSR_TXRDY
define LSR_TSRE LSR_TSRE
define COM_DATA com_data
define COM_LSR com_lsr

View File

@ -0,0 +1,192 @@
/* $NetBSD: sunxi_start.S,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2014, 2015 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#include "opt_soc.h"
#include "opt_cpuoptions.h"
#include "opt_cputypes.h"
#include "opt_multiprocessor.h"
#include "opt_arm_debug.h"
#include "opt_fdt_arm.h"
#include <arm/asm.h>
#include <arm/armreg.h>
#include "assym.h"
#include <arch/arm/sunxi/sunxi_platform.h>
RCSID("$NetBSD: sunxi_start.S,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $")
#if defined(VERBOSE_INIT_ARM) && defined(CONSADDR)
#define XPUTC(n) mov r0, n; bl xputc
#if KERNEL_BASE_VOFFSET == 0
#define XPUTC2(n) mov r0, n; bl xputc
#else
#define XPUTC2(n) mov r0, n; blx r11
#endif
#ifdef __ARMEB__
#define COM_BSWAP
#endif
#define COM_MULT 4
#define XPUTC_COM 1
#else
#define XPUTC(n)
#define XPUTC2(n)
#endif
#define INIT_MEMSIZE 64
#define TEMP_L1_TABLE (KERNEL_BASE - KERNEL_BASE_VOFFSET + INIT_MEMSIZE * L1_S_SIZE - L1_TABLE_SIZE)
#define MD_CPU_HATCH _C_LABEL(arm_fdt_cpu_hatch)
/*
* Kernel start routine for Allwinner sunxi SoCs
* At this point, this code has been loaded into SDRAM
* and the MMU maybe on or maybe off.
*/
#ifdef KERNEL_BASES_EQUAL
.text
#else
.section .start,"ax",%progbits
#endif
.global _C_LABEL(sunxi_start)
_C_LABEL(sunxi_start):
#ifdef __ARMEB__
setend be /* force big endian */
#endif
mov r9, #0
/* Move into supervisor mode and disable IRQs/FIQs. */
cpsid if, #PSR_SVC32_MODE
/*
* Save any arguments passed to us.
*/
movw r4, #:lower16:uboot_args
movt r4, #:upper16:uboot_args
sub r4, r4, #KERNEL_BASE_VOFFSET
stmia r4, {r0-r3} // Save the arguments
/* Add DTB PA (1MB) from r2 to MMU init table */
movw r3, #:lower16:(L1_S_SIZE - 1) /* align DTB PA to 1M */
movt r3, #:upper16:(L1_S_SIZE - 1)
bic r0, r2, r3
orr r0, r0, #1 /* 1MB mapping */
bic r1, r2, r3
movw r3, #:lower16:(L1_S_PROTO_armv7|L1_S_APv7_KRW|L1_S_CACHEABLE)
movt r3, #:upper16:(L1_S_PROTO_armv7|L1_S_APv7_KRW|L1_S_CACHEABLE)
orr r1, r1, r3
adr r3, .Lmmu_init_table_dtb /* table entry addr */
stmia r3, {r0-r1} /* patch table entry */
/*
* Turn on the SMP bit
*/
bl cortex_init
/*
* Set up a preliminary mapping in the MMU to allow us to run
* at KERNEL_BASE with caches on.
*/
movw r0, #:lower16:TEMP_L1_TABLE
movt r0, #:upper16:TEMP_L1_TABLE
movw r1, #:lower16:.Lmmu_init_table
movt r1, #:upper16:.Lmmu_init_table
bl arm_boot_l1pt_init
XPUTC(#'D')
/*
* Turn on the MMU, Caches, etc. Return to new enabled address space.
*/
movw r0, #:lower16:TEMP_L1_TABLE
movt r0, #:upper16:TEMP_L1_TABLE
#if KERNEL_BASE_VOFFSET == 0
bl arm_cpuinit
#else
/*
* After the MMU is on, we can execute in the normal .text segment
* so setup the lr to be in .text. Cache the address for xputc
* before we go.
*/
#if defined(VERBOSE_INIT_ARM)
adr r11, xputc @ for XPUTC2
#endif
movw lr, #:lower16:1f
movt lr, #:upper16:1f
b arm_cpuinit
.pushsection .text,"ax",%progbits
1:
#endif
XPUTC2(#'Z')
/*
* Jump to start in locore.S, which in turn will call initarm and main.
*/
b start
/* NOTREACHED */
#ifndef KERNEL_BASES_EQUAL
.popsection
#endif
#include <arm/cortex/a9_mpsubr.S>
.Lmmu_init_table:
MMU_INIT(KERNEL_BASE, KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE,
L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE)
#if KERNEL_BASE_VOFFSET != 0
/* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable, shareable */
MMU_INIT(KERNEL_BASE - KERNEL_BASE_VOFFSET,
KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE,
L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE)
#endif
/* Map CORE */
MMU_INIT(SUNXI_CORE_VBASE, SUNXI_CORE_PBASE,
(SUNXI_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
/* Map CORE */
MMU_INIT(SUNXI_CORE_PBASE, SUNXI_CORE_PBASE,
(SUNXI_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
.Lmmu_init_table_dtb:
/* Map DTB from bootloader (patched in later) */
MMU_INIT(0, 0, 0, 0)
/* end of table */
MMU_INIT(0, 0, 0, 0)
END(_C_LABEL(sunxi_start))

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.kern.inc,v 1.256 2017/01/11 12:19:43 joerg Exp $
# $NetBSD: Makefile.kern.inc,v 1.256.8.1 2017/07/18 19:13:09 snj Exp $
#
# This file contains common `MI' targets and definitions and it is included
# at the bottom of each `MD' ${MACHINE}/conf/Makefile.${MACHINE}.
@ -534,6 +534,26 @@ build_kernel: .USE
@${KCOMPILE.s} -pg
.endif # ___USE_SUFFIX_RULES___
# Begin DTS handling
DTSINC?=$S/external/gpl2/dts/dist/include
DTSPATH?=$S/external/gpl2/dts/dist/arch/${MACHINE_CPU}/boot/dts
DTSPADDING?=1024
.SUFFIXES: .dtb .dts
.dts.dtb:
${CPP} -P -xassembler-with-cpp -I ${DTSINC} -I ${DTSPATH} \
-include ${.IMPSRC} /dev/null | \
${TOOL_DTC} -i ${DTSINC} -i ${DTSPATH} -I dts -O dtb \
-p ${DTSPADDING} -b 0 -o ${.TARGET}
.PATH.dts: ${DTSPATH}
DTB= ${DTS:.dts=.dtb}
all: ${DTB}
# End DTS handling
##
## the end
##

View File

@ -1,7 +1,7 @@
# $NetBSD: files,v 1.1173.2.2 2017/06/10 05:57:08 snj Exp $
# $NetBSD: files,v 1.1173.2.3 2017/07/18 19:13:09 snj Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20150846
version 20170615
#
# device classes
@ -1505,6 +1505,9 @@ file dev/pud/pud_dev.c pud
# device-mapper driver for LVM
include "dev/dm/files.dm"
# LED framework
file dev/led.c leds
#
# File systems
#

153
sys/dev/fdt/ehci_fdt.c Normal file
View File

@ -0,0 +1,153 @@
/* $NetBSD: ehci_fdt.c,v 1.2.4.2 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ehci_fdt.c,v 1.2.4.2 2017/07/18 19:13:09 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_mem.h>
#include <dev/usb/ehcireg.h>
#include <dev/usb/ehcivar.h>
#include <dev/fdt/fdtvar.h>
static int ehci_fdt_match(device_t, cfdata_t, void *);
static void ehci_fdt_attach(device_t, device_t, void *);
CFATTACH_DECL2_NEW(ehci_fdt, sizeof(struct ehci_softc),
ehci_fdt_match, ehci_fdt_attach, NULL,
ehci_activate, NULL, ehci_childdet);
static int
ehci_fdt_match(device_t parent, cfdata_t cf, void *aux)
{
const char * const compatible[] = {
"generic-ehci",
NULL
};
struct fdt_attach_args * const faa = aux;
return of_match_compatible(faa->faa_phandle, compatible);
}
static void
ehci_fdt_attach(device_t parent, device_t self, void *aux)
{
struct ehci_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
struct fdtbus_reset *rst;
struct fdtbus_phy *phy;
struct clk *clk;
char intrstr[128];
bus_addr_t addr;
bus_size_t size;
int error;
void *ih;
u_int n;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
/* Enable clocks */
for (n = 0; (clk = fdtbus_clock_get_index(phandle, n)) != NULL; n++)
if (clk_enable(clk) != 0) {
aprint_error(": couldn't enable clock #%d\n", n);
return;
}
/* De-assert resets */
for (n = 0; (rst = fdtbus_reset_get_index(phandle, n)) != NULL; n++)
if (fdtbus_reset_deassert(rst) != 0) {
aprint_error(": couldn't de-assert reset #%d\n", n);
return;
}
/* Enable optional phy */
phy = fdtbus_phy_get(phandle, "usb");
if (phy && fdtbus_phy_enable(phy, true) != 0) {
aprint_error(": couldn't enable phy\n");
return;
}
sc->sc_dev = self;
sc->sc_bus.ub_hcpriv = sc;
sc->sc_bus.ub_dmatag = faa->faa_dmat;
sc->sc_bus.ub_revision = USBREV_2_0;
if (of_hasprop(phandle, "has-transaction-translator"))
sc->sc_flags |= EHCIF_ETTF;
else
sc->sc_ncomp = 1;
sc->sc_id_vendor = 0;
strlcpy(sc->sc_vendor, "Generic", sizeof(sc->sc_vendor));
sc->sc_size = size;
sc->iot = faa->faa_bst;
if (bus_space_map(sc->iot, addr, size, 0, &sc->ioh) != 0) {
aprint_error(": couldn't map registers\n");
return;
}
aprint_naive("\n");
aprint_normal(": EHCI\n");
/* Disable interrupts */
sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
EOWRITE4(sc, EHCI_USBINTR, 0);
if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
aprint_error_dev(self, "failed to decode interrupt\n");
return;
}
ih = fdtbus_intr_establish(phandle, 0, IPL_USB, FDT_INTR_MPSAFE,
ehci_intr, sc);
if (ih == NULL) {
aprint_error_dev(self, "couldn't establish interrupt on %s\n",
intrstr);
return;
}
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
error = ehci_init(sc);
if (error) {
aprint_error_dev(self, "init failed, error = %d\n", error);
return;
}
sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
}

181
sys/dev/fdt/fdt_phy.c Normal file
View File

@ -0,0 +1,181 @@
/* $NetBSD: fdt_phy.c,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
* 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 ``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 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fdt_phy.c,v 1.1.4.2 2017/07/18 19:13:09 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kmem.h>
#include <libfdt.h>
#include <dev/fdt/fdtvar.h>
struct fdtbus_phy_controller {
device_t pc_dev;
int pc_phandle;
const struct fdtbus_phy_controller_func *pc_funcs;
struct fdtbus_phy_controller *pc_next;
};
static struct fdtbus_phy_controller *fdtbus_pc = NULL;
int
fdtbus_register_phy_controller(device_t dev, int phandle,
const struct fdtbus_phy_controller_func *funcs)
{
struct fdtbus_phy_controller *pc;
pc = kmem_alloc(sizeof(*pc), KM_SLEEP);
pc->pc_dev = dev;
pc->pc_phandle = phandle;
pc->pc_funcs = funcs;
pc->pc_next = fdtbus_pc;
fdtbus_pc = pc;
return 0;
}
static struct fdtbus_phy_controller *
fdtbus_get_phy_controller(int phandle)
{
struct fdtbus_phy_controller *pc;
for (pc = fdtbus_pc; pc; pc = pc->pc_next) {
if (pc->pc_phandle == phandle) {
return pc;
}
}
return NULL;
}
struct fdtbus_phy *
fdtbus_phy_get_index(int phandle, u_int index)
{
struct fdtbus_phy_controller *pc;
struct fdtbus_phy *phy = NULL;
void *phy_priv = NULL;
uint32_t *phys = NULL;
uint32_t *p;
u_int n, phy_cells;
int len, resid;
len = OF_getproplen(phandle, "phys");
if (len <= 0)
return NULL;
phys = kmem_alloc(len, KM_SLEEP);
if (OF_getprop(phandle, "phys", phys, len) != len) {
kmem_free(phys, len);
return NULL;
}
p = phys;
for (n = 0, resid = len; resid > 0; n++) {
const int pc_phandle =
fdtbus_get_phandle_from_native(be32toh(p[0]));
if (of_getprop_uint32(pc_phandle, "#phy-cells", &phy_cells))
break;
if (n == index) {
pc = fdtbus_get_phy_controller(pc_phandle);
if (pc == NULL)
goto done;
phy_priv = pc->pc_funcs->acquire(pc->pc_dev,
phy_cells > 0 ? &p[1] : NULL, phy_cells * 4);
if (phy_priv) {
phy = kmem_alloc(sizeof(*phy), KM_SLEEP);
phy->phy_pc = pc;
phy->phy_priv = phy_priv;
}
break;
}
resid -= (phy_cells + 1) * 4;
p += phy_cells + 1;
}
done:
if (phys)
kmem_free(phys, len);
return phy;
}
struct fdtbus_phy *
fdtbus_phy_get(int phandle, const char *phyname)
{
struct fdtbus_phy *phy = NULL;
char *phy_names = NULL;
const char *p;
u_int index;
int len, resid;
len = OF_getproplen(phandle, "phy-names");
if (len <= 0)
return NULL;
phy_names = kmem_alloc(len, KM_SLEEP);
if (OF_getprop(phandle, "phy-names", phy_names, len) != len) {
kmem_free(phy_names, len);
return NULL;
}
p = phy_names;
for (index = 0, resid = len; resid > 0; index++) {
if (strcmp(p, phyname) == 0) {
phy = fdtbus_phy_get_index(phandle, index);
break;
}
resid -= strlen(p);
p += strlen(p) + 1;
}
if (phy_names)
kmem_free(phy_names, len);
return phy;
}
void
fdtbus_phy_put(struct fdtbus_phy *phy)
{
struct fdtbus_phy_controller *pc = phy->phy_pc;
pc->pc_funcs->release(pc->pc_dev, phy->phy_priv);
kmem_free(phy, sizeof(*phy));
}
int
fdtbus_phy_enable(struct fdtbus_phy *phy, bool enable)
{
struct fdtbus_phy_controller *pc = phy->phy_pc;
return pc->pc_funcs->enable(pc->pc_dev, phy->phy_priv, enable);
}

View File

@ -1,6 +1,7 @@
/* $NetBSD: fdt_pinctrl.c,v 1.3 2016/10/11 13:04:57 maxv Exp $ */
/* $NetBSD: fdt_pinctrl.c,v 1.3.8.1 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
* Copyright (c) 2015 Martin Fouts
* All rights reserved.
*
@ -27,7 +28,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fdt_pinctrl.c,v 1.3 2016/10/11 13:04:57 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: fdt_pinctrl.c,v 1.3.8.1 2017/07/18 19:13:09 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -37,8 +38,8 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_pinctrl.c,v 1.3 2016/10/11 13:04:57 maxv Exp $")
#include <dev/fdt/fdtvar.h>
struct fdtbus_pinctrl_controller {
device_t pc_dev;
int pc_phandle;
void *pc_cookie;
const struct fdtbus_pinctrl_controller_func *pc_funcs;
struct fdtbus_pinctrl_controller *pc_next;
@ -47,13 +48,13 @@ struct fdtbus_pinctrl_controller {
static struct fdtbus_pinctrl_controller *fdtbus_pc = NULL;
int
fdtbus_register_pinctrl_config(void *cookie, int phandle,
fdtbus_register_pinctrl_config(device_t dev, int phandle,
const struct fdtbus_pinctrl_controller_func *funcs)
{
struct fdtbus_pinctrl_controller *pc;
pc = kmem_alloc(sizeof(*pc), KM_SLEEP);
pc->pc_cookie = cookie;
pc->pc_dev = dev;
pc->pc_phandle = phandle;
pc->pc_funcs = funcs;
@ -78,57 +79,88 @@ fdtbus_pinctrl_lookup(int phandle)
int
fdtbus_pinctrl_set_config_index(int phandle, u_int index)
{
char buf[80];
int len, handle;
struct fdtbus_pinctrl_controller *pc;
const u_int *pinctrl_data;
char buf[16];
u_int xref, pinctrl_cells;
int len, error;
snprintf(buf, 80, "pinctrl-%d", index);
snprintf(buf, sizeof(buf), "pinctrl-%u", index);
len = OF_getprop(phandle, buf, (char *)&handle,
sizeof(handle));
if (len != sizeof(int)) {
printf("%s: couldn't get %s.\n", __func__, buf);
return -1;
}
pinctrl_data = fdtbus_get_prop(phandle, buf, &len);
if (pinctrl_data == NULL)
return ENOENT;
handle = fdtbus_get_phandle_from_native(be32toh(handle));
while (len > 0) {
xref = fdtbus_get_phandle_from_native(be32toh(pinctrl_data[0]));
pc = fdtbus_pinctrl_lookup(xref);
if (pc == NULL)
return ENXIO;
pc = fdtbus_pinctrl_lookup(handle);
if (!pc) {
printf("%s: Couldn't get handle %d for %s\n", __func__, handle,
buf);
return -1;
if (of_getprop_uint32(OF_parent(xref), "#pinctrl-cells", &pinctrl_cells) != 0)
pinctrl_cells = 1;
error = pc->pc_funcs->set_config(pc->pc_dev, pinctrl_data, pinctrl_cells * 4);
if (error != 0)
return error;
pinctrl_data += pinctrl_cells;
len -= (pinctrl_cells * 4);
}
return pc->pc_funcs->set_config(pc->pc_cookie);
return 0;
}
int
fdtbus_pinctrl_set_config(int phandle, const char *cfgname)
{
int index = 0;
int len;
char *result;
char *next;
const char *pinctrl_names, *name;
int len, index;
len = OF_getproplen(phandle, "pinctrl-names");
if (len <= 0)
if ((len = OF_getproplen(phandle, "pinctrl-names")) < 0)
return -1;
result = kmem_zalloc(len, KM_SLEEP);
OF_getprop(phandle, "pinctrl-names", result, len);
next = result;
while (next - result < len) {
if (!strcmp(next, cfgname)) {
kmem_free(result, len);
pinctrl_names = fdtbus_get_string(phandle, "pinctrl-names");
for (name = pinctrl_names, index = 0; len > 0;
name += strlen(name) + 1, index++) {
if (strcmp(name, cfgname) == 0)
return fdtbus_pinctrl_set_config_index(phandle, index);
}
index++;
while (*next)
next++;
next++;
}
kmem_free(result, len);
/* Not found */
return -1;
}
static void
fdtbus_pinctrl_configure_node(int phandle)
{
char buf[256];
int child, error;
for (child = OF_child(phandle); child; child = OF_peer(child)) {
if (!fdtbus_status_okay(child))
continue;
/* Configure child nodes */
fdtbus_pinctrl_configure_node(child);
/*
* Set configuration 0 for this node. This may fail if the
* pinctrl provider is missing; that's OK, we will re-configure
* when that provider attaches.
*/
fdtbus_get_path(child, buf, sizeof(buf));
error = fdtbus_pinctrl_set_config_index(child, 0);
if (error == 0)
aprint_debug("pinctrl: set config pinctrl-0 for %s\n", buf);
else if (error != ENOENT)
aprint_debug("pinctrl: failed to set config pinctrl-0 for %s: %d\n", buf, error);
}
}
void
fdtbus_pinctrl_configure(void)
{
fdtbus_pinctrl_configure_node(OF_finddevice("/"));
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: fdt_subr.c,v 1.13 2017/06/02 01:07:53 jmcneill Exp $ */
/* $NetBSD: fdt_subr.c,v 1.13.2.1 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fdt_subr.c,v 1.13 2017/06/02 01:07:53 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: fdt_subr.c,v 1.13.2.1 2017/07/18 19:13:09 snj Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -406,3 +406,39 @@ fdtbus_status_okay(int phandle)
return strncmp(prop, "ok", 2) == 0;
}
const void *
fdtbus_get_prop(int phandle, const char *prop, int *plen)
{
const int off = fdtbus_phandle2offset(phandle);
return fdt_getprop(fdtbus_get_data(), off, prop, plen);
}
const char *
fdtbus_get_string(int phandle, const char *prop)
{
const int off = fdtbus_phandle2offset(phandle);
return fdt_getprop(fdtbus_get_data(), off, prop, NULL);
}
const char *
fdtbus_get_string_index(int phandle, const char *prop, u_int index)
{
const char *names, *name;
int len, cur;
if ((len = OF_getproplen(phandle, prop)) < 0)
return NULL;
names = fdtbus_get_string(phandle, prop);
for (name = names, cur = 0; len > 0;
name += strlen(name) + 1, cur++) {
if (index == cur)
return name;
}
return NULL;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: fdtbus.c,v 1.13 2017/05/28 00:28:17 jmcneill Exp $ */
/* $NetBSD: fdtbus.c,v 1.13.2.1 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.13 2017/05/28 00:28:17 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.13.2.1 2017/07/18 19:13:09 snj Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -40,6 +40,8 @@ __KERNEL_RCSID(0, "$NetBSD: fdtbus.c,v 1.13 2017/05/28 00:28:17 jmcneill Exp $")
#include <dev/fdt/fdtvar.h>
#include <libfdt.h>
#include "locators.h"
#define FDT_MAX_PATH 256
@ -82,13 +84,21 @@ static int
fdt_match(device_t parent, cfdata_t cf, void *aux)
{
const struct fdt_attach_args *faa = aux;
const int phandle = faa->faa_phandle;
int match;
match = of_match_compatible(faa->faa_phandle, fdtbus_compatible);
/* Check compatible string */
match = of_match_compatible(phandle, fdtbus_compatible);
if (match)
return match;
return OF_finddevice("/") == faa->faa_phandle;
/* Some /clocks nodes have no compatible string */
if (!of_hasprop(phandle, "compatible") &&
OF_finddevice("/clocks") == phandle)
return 1;
/* Always match the root node */
return OF_finddevice("/") == phandle;
}
static void
@ -275,6 +285,7 @@ fdtbus_print(void *aux, const char *pnp)
const struct fdt_attach_args * const faa = aux;
char buf[FDT_MAX_PATH];
const char *name = buf;
int len;
if (pnp && faa->faa_quiet)
return QUIET;
@ -286,9 +297,17 @@ fdtbus_print(void *aux, const char *pnp)
if (!fdtbus_get_path(faa->faa_phandle, buf, sizeof(buf)))
name = faa->faa_name;
if (pnp)
if (pnp) {
aprint_normal("%s at %s", name, pnp);
else
const char *compat = fdt_getprop(fdtbus_get_data(),
fdtbus_phandle2offset(faa->faa_phandle), "compatible",
&len);
while (len > 0) {
aprint_debug(" <%s>", compat);
len -= (strlen(compat) + 1);
compat += (strlen(compat) + 1);
}
} else
aprint_debug(" (%s)", name);
return UNCONF;

View File

@ -1,4 +1,4 @@
/* $NetBSD: fdtvar.h,v 1.20 2017/06/02 13:53:29 jmcneill Exp $ */
/* $NetBSD: fdtvar.h,v 1.20.2.1 2017/07/18 19:13:09 snj Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@ -85,7 +85,7 @@ struct fdtbus_pinctrl_pin {
};
struct fdtbus_pinctrl_controller_func {
int (*set_config)(void *);
int (*set_config)(device_t, const void *, size_t);
};
struct fdtbus_regulator_controller;
@ -172,6 +172,19 @@ struct fdtbus_power_controller_func {
void (*poweroff)(device_t);
};
struct fdtbus_phy_controller;
struct fdtbus_phy {
struct fdtbus_phy_controller *phy_pc;
void *phy_priv;
};
struct fdtbus_phy_controller_func {
void * (*acquire)(device_t, const void *, size_t);
void (*release)(device_t, void *);
int (*enable)(device_t, void *, bool);
};
struct fdt_console {
int (*match)(int);
void (*consinit)(struct fdt_attach_args *, u_int);
@ -198,7 +211,7 @@ int fdtbus_register_i2c_controller(device_t, int,
const struct fdtbus_i2c_controller_func *);
int fdtbus_register_gpio_controller(device_t, int,
const struct fdtbus_gpio_controller_func *);
int fdtbus_register_pinctrl_config(void *, int,
int fdtbus_register_pinctrl_config(device_t, int,
const struct fdtbus_pinctrl_controller_func *);
int fdtbus_register_regulator_controller(device_t, int,
const struct fdtbus_regulator_controller_func *);
@ -210,6 +223,8 @@ int fdtbus_register_dma_controller(device_t, int,
const struct fdtbus_dma_controller_func *);
int fdtbus_register_power_controller(device_t, int,
const struct fdtbus_power_controller_func *);
int fdtbus_register_phy_controller(device_t, int,
const struct fdtbus_phy_controller_func *);
int fdtbus_get_reg(int, u_int, bus_addr_t *, bus_size_t *);
int fdtbus_get_reg64(int, u_int, uint64_t *, uint64_t *);
@ -226,6 +241,7 @@ int fdtbus_gpio_read(struct fdtbus_gpio_pin *);
void fdtbus_gpio_write(struct fdtbus_gpio_pin *, int);
int fdtbus_gpio_read_raw(struct fdtbus_gpio_pin *);
void fdtbus_gpio_write_raw(struct fdtbus_gpio_pin *, int);
void fdtbus_pinctrl_configure(void);
int fdtbus_pinctrl_set_config_index(int, u_int);
int fdtbus_pinctrl_set_config(int, const char *);
struct fdtbus_regulator *fdtbus_regulator_acquire(int, const char *);
@ -254,6 +270,11 @@ void fdtbus_reset_put(struct fdtbus_reset *);
int fdtbus_reset_assert(struct fdtbus_reset *);
int fdtbus_reset_deassert(struct fdtbus_reset *);
struct fdtbus_phy *fdtbus_phy_get(int, const char *);
struct fdtbus_phy *fdtbus_phy_get_index(int, u_int);
void fdtbus_phy_put(struct fdtbus_phy *);
int fdtbus_phy_enable(struct fdtbus_phy *, bool);
int fdtbus_todr_attach(device_t, int, todr_chip_handle_t);
void fdtbus_power_reset(void);
@ -274,6 +295,10 @@ tcflag_t fdtbus_get_stdout_flags(void);
bool fdtbus_status_okay(int);
const void * fdtbus_get_prop(int, const char *, int *);
const char * fdtbus_get_string(int, const char *);
const char * fdtbus_get_string_index(int, const char *, u_int);
int fdtbus_print(void *, const char *);
#endif /* _DEV_FDT_FDTVAR_H */

View File

@ -1,4 +1,4 @@
# $NetBSD: files.fdt,v 1.16 2017/06/03 14:48:03 jmcneill Exp $
# $NetBSD: files.fdt,v 1.16.2.1 2017/07/18 19:13:09 snj Exp $
include "external/bsd/libfdt/conf/files.libfdt"
@ -18,10 +18,18 @@ device fclock: clk
attach fclock at fdt
file dev/fdt/fixedclock.c fclock
device ffclock: clk
attach ffclock at fdt
file dev/fdt/fixedfactorclock.c ffclock
device gpiokeys: sysmon_envsys, sysmon_power
attach gpiokeys at fdt
file dev/fdt/gpiokeys.c gpiokeys
device gpioleds: leds
attach gpioleds at fdt
file dev/fdt/gpioleds.c gpioleds
file dev/fdt/fdt_openfirm.c fdtbus
file dev/fdt/fdt_subr.c fdtbus
file dev/fdt/fdt_clock.c fdtbus
@ -29,6 +37,7 @@ file dev/fdt/fdt_dma.c fdtbus
file dev/fdt/fdt_gpio.c fdtbus
file dev/fdt/fdt_i2c.c fdtbus
file dev/fdt/fdt_intr.c fdtbus
file dev/fdt/fdt_phy.c fdtbus
file dev/fdt/fdt_power.c fdtbus
file dev/fdt/fdt_regulator.c fdtbus
file dev/fdt/fdt_reset.c fdtbus

Some files were not shown because too many files have changed in this diff Show More