Pull up following revision(s) (requested by jmcneill in ticket #491):
sys/arch/evbarm/conf/BEAGLEBOARD_INSTALL: file removal sys/arch/arm/ti/ti_dpll_clock.c: revision 1.2 sys/arch/arm/ti/ti_sysc.c: revision 1.1 sys/arch/arm/ti/ti_rng.c: revision 1.1 sys/arch/arm/ti/ti_rng.c: revision 1.2 sys/dev/i2c/tps65950.c: file removal sys/arch/evbarm/conf/std.ti: file removal sys/dev/i2c/files.i2c: revision 1.101 sys/dev/i2c/files.i2c: revision 1.102 sys/dev/i2c/at24cxx.c: revision 1.32 sys/dev/i2c/files.i2c: revision 1.103 sys/dev/i2c/twl4030.c: revision 1.1 sys/dev/i2c/files.i2c: revision 1.104 sys/dev/i2c/twl4030.c: revision 1.2 sys/dev/i2c/twl4030.c: revision 1.3 sys/arch/arm/ti/ti_com.c: revision 1.6 sys/arch/arm/ti/ti_com.c: revision 1.7 sys/arch/arm/ti/ti_com.c: revision 1.8 sys/dev/fdt/cpufreq_dt.c: revision 1.11 sys/arch/arm/ti/ti_iic.c: revision 1.1 sys/dev/fdt/cpufreq_dt.c: revision 1.12 sys/arch/arm/ti/ti_usb.c: revision 1.1 sys/arch/arm/ti/ti_iic.c: revision 1.2 sys/dev/fdt/cpufreq_dt.c: revision 1.13 sys/arch/arm/ti/ti_iic.c: revision 1.3 sys/arch/arm/ti/ti_iic.c: revision 1.4 sys/arch/evbarm/conf/files.ti: file removal sys/arch/evbarm/conf/BEAGLEBOARDXM: file removal sys/arch/arm/dts/omap3-n900.dts: revision 1.1 sys/arch/arm/ti/ti_edma.h: revision 1.1 sys/arch/evbarm/conf/OVERO_INSTALL: file removal sys/arch/arm/ti/ti_usbtll.c: revision 1.1 sys/arch/arm/ti/files.ti: revision 1.5 etc/etc.evbarm/Makefile.inc: revision 1.108 sys/arch/arm/ti/files.ti: revision 1.6 sys/dev/i2c/tps65217pmic.c: revision 1.13 etc/etc.evbarm/Makefile.inc: revision 1.109 sys/arch/arm/ti/files.ti: revision 1.7 sys/dev/i2c/tps65217pmic.c: revision 1.14 sys/arch/arm/ti/files.ti: revision 1.8 sys/arch/arm/ti/files.ti: revision 1.9 sys/dev/fdt/usbnopphy.c: revision 1.1 sys/arch/evbarm/conf/GENERIC: revision 1.55 sys/arch/evbarm/conf/GENERIC: revision 1.56 sys/arch/evbarm/conf/GENERIC: revision 1.57 sys/arch/evbarm/conf/GENERIC: revision 1.58 sys/arch/evbarm/conf/GENERIC: revision 1.59 sys/arch/evbarm/conf/BEAGLEBONE: file removal sys/arch/arm/ti/omap2_gpmcreg.h: revision 1.1 sys/arch/arm/ti/ti_otgreg.h: revision 1.1 sys/arch/arm/ti/ti_tptc.c: revision 1.1 sys/arch/evbarm/conf/IGEPV2: file removal sys/arch/arm/ti/am3_prcm.c: revision 1.10 sys/dev/i2c/tda19988.c: revision 1.1 sys/arch/evbarm/conf/OVERO: file removal sys/dev/i2c/tda19988.c: revision 1.2 sys/dev/i2c/tda19988.c: revision 1.3 sys/arch/arm/ti/omap3_dss.c: revision 1.1 sys/arch/evbarm/conf/BEAGLEBONE_INSTALL: file removal sys/arch/arm/ti/ti_omapintc.c: revision 1.2 etc/etc.evbarm/Makefile.inc: revision 1.112 etc/etc.evbarm/Makefile.inc: revision 1.113 sys/arch/arm/ti/ti_div_clock.c: revision 1.1 etc/etc.evbarm/Makefile.inc: revision 1.114 sys/arch/evbarm/conf/N900: revision 1.32 sys/arch/evbarm/conf/N900: revision 1.33 distrib/utils/embedded/conf/armv7.conf: revision 1.36 sys/arch/evbarm/conf/GENERIC: revision 1.60 distrib/utils/embedded/conf/armv7.conf: revision 1.37 sys/arch/arm/ti/omap2_nand.c: revision 1.1 sys/arch/evbarm/conf/GENERIC: revision 1.61 sys/arch/arm/ti/omap2_nand.c: revision 1.2 sys/arch/evbarm/conf/GENERIC: revision 1.62 distrib/utils/embedded/conf/armv7.conf: revision 1.39 sys/arch/evbarm/conf/GENERIC: revision 1.63 sys/arch/arm/ti/ti_fb.c: revision 1.1 sys/arch/evbarm/conf/GENERIC: revision 1.64 sys/arch/evbarm/conf/GENERIC: revision 1.65 sys/arch/evbarm/conf/GENERIC: revision 1.66 sys/arch/evbarm/conf/GENERIC: revision 1.67 sys/arch/arm/ti/ti_platform.c: revision 1.7 sys/arch/arm/ti/ti_platform.c: revision 1.8 sys/arch/arm/ti/am3_prcm.c: revision 1.2 sys/arch/arm/ti/ti_platform.c: revision 1.9 sys/arch/arm/ti/am3_prcm.c: revision 1.3 sys/arch/arm/ti/am3_prcm.c: revision 1.4 sys/arch/arm/ti/am3_prcm.c: revision 1.5 sys/arch/arm/ti/am3_prcm.c: revision 1.6 sys/arch/arm/ti/am3_prcm.c: revision 1.7 sys/arch/evbarm/conf/DEVKIT8000: file removal sys/arch/arm/ti/am3_prcm.c: revision 1.8 sys/arch/arm/ti/am3_prcm.c: revision 1.9 sys/dev/fdt/syscon.c: revision 1.4 sys/arch/arm/ti/files.ti: revision 1.10 sys/arch/arm/ti/ti_mux_clock.c: revision 1.1 sys/arch/arm/ti/ti_sdhc.c: revision 1.1 sys/arch/arm/ti/files.ti: revision 1.11 sys/arch/arm/ti/if_cpswreg.h: revision 1.1 sys/arch/arm/ti/ti_sdhc.c: revision 1.2 sys/arch/arm/ti/files.ti: revision 1.12 sys/arch/arm/ti/ti_sdhc.c: revision 1.3 sys/arch/arm/ti/files.ti: revision 1.13 sys/arch/arm/ti/files.ti: revision 1.14 sys/arch/arm/ti/files.ti: revision 1.15 sys/arch/arm/ti/files.ti: revision 1.16 sys/arch/arm/ti/omap3_cm.c: revision 1.1 sys/arch/arm/ti/files.ti: revision 1.17 sys/arch/arm/ti/omap3_cm.c: revision 1.2 sys/arch/arm/ti/files.ti: revision 1.18 sys/arch/arm/ti/omap3_cm.c: revision 1.3 sys/arch/arm/ti/files.ti: revision 1.19 sys/arch/arm/ti/omap3_cm.c: revision 1.4 sys/arch/arm/ti/ti_motg.c: revision 1.1 sys/arch/arm/ti/ti_rngreg.h: revision 1.1 sys/arch/arm/ti/ti_sdhcreg.h: revision 1.1 sys/arch/arm/dts/omap3-beagle-xm.dts: revision 1.1 sys/arch/arm/ti/am3_platform.c: revision 1.1 sys/arch/arm/ti/ti_sdhcreg.h: revision 1.2 sys/arch/arm/ti/ti_lcdc.h: revision 1.1 sys/arch/evbarm/conf/BEAGLEBOARDXM_INSTALL: file removal sys/arch/evbarm/conf/README.evbarm: revision 1.22 sys/arch/evbarm/conf/README.evbarm: revision 1.23 sys/arch/arm/ti/ti_platform.c: file removal sys/arch/evbarm/conf/README.evbarm: revision 1.24 sys/arch/arm/ti/ti_omaptimer.c: revision 1.2 sys/arch/arm/ti/ti_prcm.c: revision 1.2 sys/arch/evbarm/conf/README.evbarm: revision 1.25 sys/arch/arm/ti/ti_omaptimer.c: revision 1.3 sys/arch/arm/ti/ti_prcm.c: revision 1.3 sys/arch/evbarm/conf/README.evbarm: revision 1.26 sys/arch/arm/ti/ti_omaptimer.c: revision 1.4 sys/arch/evbarm/conf/README.evbarm: revision 1.27 sys/arch/arm/ti/ti_ehci.c: revision 1.1 sys/arch/arm/ti/files.ti: revision 1.20 sys/arch/arm/ti/ti_cpufreq.c: revision 1.1 sys/arch/arm/ti/ti_cpufreq.c: revision 1.2 sys/arch/arm/fdt/smsh_fdt.c: revision 1.2 sys/arch/arm/ti/omap3_dssreg.h: revision 1.1 sys/arch/evbarm/conf/OVERO: revision 1.56 sys/arch/evbarm/conf/TI: file removal sys/arch/arm/dts/omap3-beagle.dts: revision 1.1 sys/dev/fdt/fdtvar.h: revision 1.55 sys/dev/fdt/fdtvar.h: revision 1.56 distrib/utils/embedded/files/armv7_boot_nonefi.cmd: revision 1.2 sys/dev/fdt/fdt_phy.c: revision 1.6 sys/arch/arm/ti/ti_iicreg.h: revision 1.1 sys/arch/arm/ti/ti_lcdc.c: revision 1.1 sys/arch/arm/ti/ti_gpio.c: revision 1.1 sys/arch/arm/ti/ti_iicreg.h: revision 1.2 sys/arch/arm/ti/ti_lcdc.c: revision 1.2 sys/dev/fdt/files.fdt: revision 1.46 sys/arch/arm/ti/ti_gpio.c: revision 1.2 sys/arch/arm/ti/ti_iicreg.h: revision 1.3 sys/arch/arm/ti/ti_lcdc.c: revision 1.3 sys/dev/fdt/files.fdt: revision 1.47 sys/arch/arm/ti/ti_gpio.c: revision 1.3 sys/dev/fdt/pinctrl_single.c: revision 1.1 sys/arch/evbarm/conf/files.generic: revision 1.9 sys/arch/arm/ti/ti_gpmc.c: revision 1.1 sys/arch/arm/ti/ti_lcdcreg.h: revision 1.1 sys/arch/evbarm/conf/BEAGLEBOARD: file removal sys/arch/arm/ti/omap3_prm.c: revision 1.1 sys/arch/arm/ti/ti_platform.h: file removal sys/arch/arm/ti/omap3_platform.c: revision 1.1 sys/arch/arm/ti/ti_prcm.h: revision 1.2 sys/arch/arm/ti/omap3_platform.c: revision 1.2 sys/arch/arm/ti/ti_prcm.h: revision 1.3 sys/arch/arm/ti/ti_prcm.h: revision 1.4 sys/dev/fdt/fdt_clock.c: revision 1.9 sys/arch/arm/ti/ti_edma.c: revision 1.1 sys/arch/arm/ti/ti_otg.c: revision 1.1 distrib/utils/embedded/files/armv7_boot.cmd: revision 1.15 sys/arch/arm/ti/if_cpsw.c: revision 1.7 sys/arch/evbarm/conf/std.igepv2: file removal sys/arch/arm/ti/if_cpsw.c: revision 1.8 sys/arch/arm/ti/ti_dpll_clock.c: revision 1.1 Adapt ti fdt glue to support GENERIC kernel. Do not search 64-bit directories for dts files Fix am33xx_platform_early_putchar for pre-MMU output Add bus driver for TI sysc interconncet. Make com work again Add EDMA TPCC and TPTC drivers. Add driver for one-register-per-pin type pinctrl devices. Add MMCHS support. Add USB support. Disable autoidle Place devmap above KERNEL_IO_VBASE Use Timer2 for timecounter, and enable hw module. Add support for TI AM335x Add atmel,24c256 compat data Add I2C support. Add tiiic, tps65217pmic Add FDT support Fix early putchar, add reset func No support for tegra210 in armv7 kernel Switch to GENERIC kernels only. Get mac address from DT Skip nodes with an "opp-suspend" property and fix tables that have disabled nodes in the middle. enumerate devices under child "clocks" node Add support for platform specific opp table filters. Add fdtbus_clock_count to count the number of clock references on a given node enumerate devices under child "clocks" node Add AM335x DVFS support. Enable TI AM335x DVFS support Add support for GPIO controller. Add tigpio Unhook BEAGLEBONE kernel from the build Remove BEAGLEBONE kernel config (AM335x SoC is supported by GENERIC now). Add support for hardware RNG. Add tirng Add explicit FDT_OPP for operating-points-v2 so the link set won't be empty Rename SOC_TI_AM335X to SOC_AM33XX and rename ti_platform.c to am3_platform.c Set stdout-path on TI OMAP3 BeagleBoard Add support for TI OMAP3. Add OMAP3 support. Move a lot of *.dtb files to a dtb/ subdirectory on the FAT partition. Mkimage (eroneously) creates a FAT16 partition (despite the configuration asking for FAT32), and that has a root directory size limit. Idea from Jared. Skip xref if it is 0 Add generic USB PHY driver Add driver for TI TWL4030 Power Management IC Use the hwmod clk to get the timer rate and explicitly enable the timecounter timer. Add OMAP3 USB support. Add twl, usbnopphy, tiusb, tiusbtll Move omap3 dtb files to /boot/dtb Remove BEAGLEBOARD kernel from list of kernels to build Remove BEAGLEBOARD kernel (supported by GENERIC now) Fix PRM_RSTCTRL_RST_DPLL3 definition, now reset works. Remove DEVKIT8000 kernel (GENERIC should work now) Remove DPLL5 init ported from old omap code, it is not required Set the stdout-path on xM like Ti OMAP3 BeagleBoard Remove BEAGLEBOARDXM from the build Remove BEAGLEBOARDXM kernel (supported by GENERIC now) Handle different register layout on OMAP3 Add omapfb to FDT-ized TI port. Use dss as console on Nokia N900. Enable IRQ status bits for omap3 type and set speed properly Add RTC support Remove tps65950pm (hardware now supported by twl4030.c) Add NAND flash support. Add tigpmc, omapnand Attach tiusb before the default pass since it adds a bus to reduce kernel output Replace tps65950pm with twl (the former has been removed) Fix non-FDT build Cleanup and remove dependency on arch/arm/omap Add support for GPIO interrupts and fix reading the state of output pins. Match smsc,lan9115 and honour local-mac-address/mac-address properties Only one instance of twl(4) is needed Remove OVERO from build, and commented out N900 kernel config OMAP3 SoC and all peripherals in the OVERO kernel are now supported by GENERIC. Remove commented out IGEPV2 entry OMAP3 SoC and all peripherals in the IGEPV2 kernel are now supported by GENERIC. No longer used. Also match ti,omap2-onenand Defer power monitor polling to the sysmon taskq thread to avoid i2c transactions in intr context Add driver for NXP TDA19988 HDMI encoder Add support for AM335x display controller (LCDC). Add tdahdmi, tilcdc, tifb Test DRM_MODE_* flags, not VID_* Comment out mode fixup (not needed it seems) Use 297MHz for display clock Select closest rate to desired pixel clock Speed up mode setting a bit and turn off the display while changing modes
This commit is contained in:
parent
94154007c4
commit
51b681bfe9
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: armv7.conf,v 1.35 2019/07/21 16:05:24 rin Exp $
|
||||
# $NetBSD: armv7.conf,v 1.35.2.1 2019/11/27 13:46:45 martin Exp $
|
||||
# ARMv7 customization script used by mkimage
|
||||
#
|
||||
board=armv7
|
||||
|
@ -7,10 +7,7 @@ resize=true
|
|||
|
||||
. ${DIR}/conf/evbarm.conf
|
||||
|
||||
# altera, exynos, sunxi, tegra
|
||||
kernels_generic="GENERIC"
|
||||
# non-FDTised / special kernels
|
||||
kernels_beagle="BEAGLEBOARD BEAGLEBONE"
|
||||
|
||||
make_label() {
|
||||
make_label_evbarm
|
||||
|
@ -50,10 +47,6 @@ populate_common() {
|
|||
"${MKUBOOTIMAGE}" -A arm -C none -O netbsd -T script -a 0 -n "NetBSD/armv7 boot" "${mnt}/boot/boot.cmd" "${mnt}/boot/boot.scr"
|
||||
}
|
||||
|
||||
populate_beagle() {
|
||||
:
|
||||
}
|
||||
|
||||
populate_rpi() {
|
||||
firmwaredir="${src}/external/broadcom/rpi-firmware/dist"
|
||||
firmwarefiles="LICENCE.broadcom bootcode.bin fixup.dat fixup_cd.dat start.elf start_cd.elf"
|
||||
|
@ -105,10 +98,6 @@ EOF
|
|||
>> "$tmp/selected_sets"
|
||||
}
|
||||
|
||||
populate_altera() {
|
||||
:
|
||||
}
|
||||
|
||||
populate_amlogic() {
|
||||
odroidc1_kernelimg=netbsd-GENERIC.ub
|
||||
|
||||
|
@ -117,24 +106,16 @@ populate_amlogic() {
|
|||
ODROIDC-UBOOT-CONFIG
|
||||
|
||||
setenv bootargs "awge0.mac-address=\${ethaddr}"
|
||||
setenv bootcmd "fatload mmc 0:1 0x21000000 ${odroidc1_kernelimg}; fatload mmc 0:1 0x20000000 meson8b-odroidc1.dtb; bootm 0x21000000 - 0x20000000"
|
||||
setenv bootcmd "fatload mmc 0:1 0x21000000 ${odroidc1_kernelimg}; fatload mmc 0:1 0x20000000 dtb/meson8b-odroidc1.dtb; bootm 0x21000000 - 0x20000000"
|
||||
run bootcmd
|
||||
EOF
|
||||
}
|
||||
|
||||
populate_sunxi() {
|
||||
:
|
||||
}
|
||||
|
||||
populate_tegra() {
|
||||
:
|
||||
}
|
||||
|
||||
populate() {
|
||||
echo "${bar} looking for kernels in ${kernel} ${bar}"
|
||||
kernels=""
|
||||
# .ub kernels
|
||||
for k in $kernels_generic $kernels_beagle; do
|
||||
for k in $kernels_generic; do
|
||||
f="${kernel}/netbsd-${k}.ub.gz"
|
||||
test -f "${f}" && kernels="${kernels} ${f}"
|
||||
done
|
||||
|
@ -154,28 +135,34 @@ populate() {
|
|||
done
|
||||
done
|
||||
|
||||
# "kernels" includes some .dtb files that should go into a separate
|
||||
# directory
|
||||
mkdir -p "${mnt}/boot/dtb"
|
||||
|
||||
# install kernels to /boot partition
|
||||
for k in ${kernels}; do
|
||||
tgt="$(basename ${k} | sed 's/\.gz$//')"
|
||||
echo "${bar} installing ${k} to /boot/${tgt} ${bar}"
|
||||
case "${tgt}" in
|
||||
sun*.dtb|am335x-*.dtb|omap3-*.dtb|meson8b-*.dtb|tegra*.dtb|vexpress*.dtb)
|
||||
pfx="dtb/";;
|
||||
*)
|
||||
pfx=;;
|
||||
esac
|
||||
echo "${bar} installing ${k} to /boot/${tgt} (on ${mnt}, pfx=${pfx}) ${bar}"
|
||||
case "${k}" in
|
||||
*.gz)
|
||||
${GZIP_CMD} -dc "${k}" > "${mnt}/boot/${tgt}"
|
||||
${GZIP_CMD} -dc "${k}" > "${mnt}/boot/${pfx}${tgt}"
|
||||
;;
|
||||
*)
|
||||
cp "${k}" "${mnt}/boot/${tgt}"
|
||||
cp "${k}" "${mnt}/boot/${pfx}${tgt}"
|
||||
;;
|
||||
esac ||
|
||||
fail "Copy of ${k} to ${mnt}/boot/${tgt} failed"
|
||||
done
|
||||
|
||||
# board specific configuration
|
||||
populate_altera
|
||||
populate_amlogic
|
||||
populate_beagle
|
||||
populate_rpi
|
||||
populate_sunxi
|
||||
populate_tegra
|
||||
|
||||
# common configuration
|
||||
populate_common
|
||||
|
|
|
@ -1,21 +1,8 @@
|
|||
if test "${board}" = "am335x" ; then
|
||||
setenv kernel netbsd-BEAGLEBONE.ub
|
||||
setenv mmcpart 0:1
|
||||
setenv bootargs root=ld0a
|
||||
else
|
||||
setenv use_efi 1
|
||||
fi
|
||||
|
||||
if test "${soc}" = "tegra210" ; then
|
||||
# enable PCIe
|
||||
pci enum
|
||||
fi
|
||||
|
||||
if test "${use_efi}" = "1" ; then
|
||||
setenv boot_scripts
|
||||
setenv boot_script_dhcp
|
||||
run distro_bootcmd
|
||||
else
|
||||
fatload mmc ${mmcpart} ${kernel_addr_r} ${kernel}
|
||||
bootm ${kernel_addr_r} ${bootargs}
|
||||
fi
|
||||
setenv boot_scripts
|
||||
setenv boot_script_dhcp
|
||||
run distro_bootcmd
|
||||
|
|
|
@ -33,15 +33,6 @@ if test "${soc}" = "tegra124" ; then
|
|||
setenv mmcpart 1:1
|
||||
setenv use_fdt 1
|
||||
fi
|
||||
if test "${soc}" = "tegra210" ; then
|
||||
setenv kernel netbsd.ub
|
||||
setenv bootargs root=wd0a
|
||||
setenv mmcpart 1:1
|
||||
setenv use_fdt 1
|
||||
setenv fdtfile ${soc}-${board}.dtb
|
||||
# enable PCIe
|
||||
pci enum
|
||||
fi
|
||||
|
||||
if test "${kernel}" = "" ; then
|
||||
echo '>>>'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile.inc,v 1.107 2019/06/02 17:13:15 thorpej Exp $
|
||||
# $NetBSD: Makefile.inc,v 1.107.2.1 2019/11/27 13:46:45 martin Exp $
|
||||
#
|
||||
# etc.evbarm/Makefile.inc -- evbarm-specific etc Makefile targets
|
||||
#
|
||||
|
@ -82,30 +82,20 @@ EVBARM_BOARDS.armv7+= BCM5301X
|
|||
EVBARM_BOARDS.armv7hf+= BCM5301X
|
||||
#EVBARM_BOARDS.armv7+= BCM56340
|
||||
#EVBARM_BOARDS.armv7hf+= BCM56340
|
||||
KERNEL_SETS.armv7+= BEAGLEBOARD
|
||||
KERNEL_SETS.armv7hf+= BEAGLEBOARD
|
||||
EVBARM_BOARDS.armv7+= BEAGLEBOARDXM
|
||||
EVBARM_BOARDS.armv7hf+= BEAGLEBOARDXM
|
||||
KERNEL_SETS.armv7+= BEAGLEBONE
|
||||
KERNEL_SETS.armv7hf+= BEAGLEBONE
|
||||
EVBARM_BOARDS.armv7+= CUBOX
|
||||
EVBARM_BOARDS.armv7hf+= CUBOX
|
||||
EVBARM_BOARDS.armv7+= CUBOX-I
|
||||
EVBARM_BOARDS.armv7hf+= CUBOX-I
|
||||
#EVBARM_BOARDS.armv7+= IGEPV2
|
||||
EVBARM_BOARDS.armv7+= IMX6UL-STARTER
|
||||
EVBARM_BOARDS.armv7hf+= IMX6UL-STARTER
|
||||
EVBARM_BOARDS.armv7+= KOBO
|
||||
EVBARM_BOARDS.armv7hf+= KOBO
|
||||
EVBARM_BOARDS.armv7+= MIRABOX
|
||||
EVBARM_BOARDS.armv7hf+= MIRABOX
|
||||
#EVBARM_BOARDS.armv7+= N900
|
||||
EVBARM_BOARDS.armv7+= NETWALKER
|
||||
EVBARM_BOARDS.armv7hf+= NETWALKER
|
||||
EVBARM_BOARDS.armv7+= OMAP5EVM
|
||||
EVBARM_BOARDS.armv7hf+= OMAP5EVM
|
||||
EVBARM_BOARDS.armv7+= OVERO
|
||||
EVBARM_BOARDS.armv7hf+= OVERO
|
||||
EVBARM_BOARDS.armv7+= PANDABOARD
|
||||
EVBARM_BOARDS.armv7hf+= PANDABOARD
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* $NetBSD: omap3-beagle-xm.dts,v 1.1.2.2 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Sevan Janiyan <sevan@NetBSD.org>
|
||||
*
|
||||
* 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_next "omap3-beagle-xm.dts"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
stdout-path = &uart3;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
/* $NetBSD: omap3-beagle.dts,v 1.1.2.2 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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_next "omap3-beagle.dts"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
stdout-path = &uart3;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
/* $NetBSD: omap3-n900.dts,v 1.1.2.2 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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_next "omap3-n900.dts"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
stdout-path = &dss;
|
||||
};
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: smsh_fdt.c,v 1.1 2017/06/02 10:46:07 jmcneill Exp $ */
|
||||
/* $NetBSD: smsh_fdt.c,v 1.1.18.1 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: smsh_fdt.c,v 1.1 2017/06/02 10:46:07 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: smsh_fdt.c,v 1.1.18.1 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -49,7 +49,11 @@ __KERNEL_RCSID(0, "$NetBSD: smsh_fdt.c,v 1.1 2017/06/02 10:46:07 jmcneill Exp $"
|
|||
static int smsh_fdt_match(device_t, cfdata_t, void *);
|
||||
static void smsh_fdt_attach(device_t, device_t, void *);
|
||||
|
||||
static const char * const compatible[] = { "smsc,lan9118", NULL };
|
||||
static const char * const compatible[] = {
|
||||
"smsc,lan9118",
|
||||
"smsc,lan9115",
|
||||
NULL
|
||||
};
|
||||
|
||||
CFATTACH_DECL_NEW(smsh_fdt, sizeof(struct lan9118_softc),
|
||||
smsh_fdt_match, smsh_fdt_attach, NULL, NULL);
|
||||
|
@ -67,10 +71,12 @@ smsh_fdt_attach(device_t parent, device_t self, void *aux)
|
|||
{
|
||||
struct lan9118_softc * const sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
char intrstr[128];
|
||||
const int phandle = faa->faa_phandle;
|
||||
const char *enaddr;
|
||||
char intrstr[128];
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
int len;
|
||||
void *ih;
|
||||
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
|
||||
|
@ -95,6 +101,14 @@ smsh_fdt_attach(device_t parent, device_t self, void *aux)
|
|||
if (of_hasprop(phandle, "smsc,irq-push-pull"))
|
||||
sc->sc_flags |= LAN9118_FLAGS_IRQ_PP;
|
||||
|
||||
enaddr = fdtbus_get_prop(phandle, "local-mac-address", &len);
|
||||
if (enaddr == NULL || len != ETHER_ADDR_LEN)
|
||||
enaddr = fdtbus_get_prop(phandle, "mac-address", &len);
|
||||
if (enaddr != NULL && len == ETHER_ADDR_LEN) {
|
||||
memcpy(sc->sc_enaddr, enaddr, ETHER_ADDR_LEN);
|
||||
sc->sc_flags |= LAN9118_FLAGS_NO_EEPROM;
|
||||
}
|
||||
|
||||
if (lan9118_attach(sc) != 0)
|
||||
goto unmap;
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* $NetBSD: ti_platform.c,v 1.6 2018/10/30 16:41:52 skrll Exp $ */
|
||||
/* $NetBSD: am3_platform.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
#include "opt_console.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_platform.c,v 1.6 2018/10/30 16:41:52 skrll Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: am3_platform.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
|
@ -14,6 +14,8 @@ __KERNEL_RCSID(0, "$NetBSD: ti_platform.c,v 1.6 2018/10/30 16:41:52 skrll Exp $"
|
|||
|
||||
#include <dev/ic/comreg.h>
|
||||
|
||||
#include <arch/evbarm/fdt/platform.h>
|
||||
|
||||
extern struct bus_space armv7_generic_bs_tag;
|
||||
extern struct bus_space armv7_generic_a4x_bs_tag;
|
||||
extern struct arm32_bus_dma_tag arm_generic_dma_tag;
|
||||
|
@ -24,8 +26,10 @@ void
|
|||
am33xx_platform_early_putchar(char c)
|
||||
{
|
||||
#ifdef CONSADDR
|
||||
#define CONSADDR_VA ((CONSADDR - 0x44c00000) + 0xe4c00000)
|
||||
volatile uint32_t *uartaddr = (volatile uint32_t *)CONSADDR_VA;
|
||||
#define CONSADDR_VA ((CONSADDR - 0x44c00000) + (KERNEL_IO_VBASE | 0x04c00000))
|
||||
volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
|
||||
(volatile uint32_t *)CONSADDR_VA :
|
||||
(volatile uint32_t *)CONSADDR;
|
||||
|
||||
while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
|
||||
;
|
||||
|
@ -39,9 +43,9 @@ static const struct pmap_devmap *
|
|||
am33xx_platform_devmap(void)
|
||||
{
|
||||
static const struct pmap_devmap devmap[] = {
|
||||
DEVMAP_ENTRY(0xe4c00000, 0x44c00000, 0x00400000),
|
||||
DEVMAP_ENTRY(0xe8000000, 0x48000000, 0x01000000),
|
||||
DEVMAP_ENTRY(0xea000000, 0x4a000000, 0x01000000),
|
||||
DEVMAP_ENTRY(KERNEL_IO_VBASE | 0x04c00000, 0x44c00000, 0x00400000),
|
||||
DEVMAP_ENTRY(KERNEL_IO_VBASE | 0x08000000, 0x48000000, 0x01000000),
|
||||
DEVMAP_ENTRY(KERNEL_IO_VBASE | 0x0a000000, 0x4a000000, 0x01000000),
|
||||
DEVMAP_ENTRY_END
|
||||
};
|
||||
|
||||
|
@ -118,28 +122,29 @@ am33xx_platform_delay(u_int n)
|
|||
prev = bus_space_read_4(bst, bsh, 0x3c);
|
||||
while (ticks > 0) {
|
||||
cur = bus_space_read_4(bst, bsh, 0x3c);
|
||||
if (cur > prev)
|
||||
if (cur >= prev)
|
||||
ticks -= (cur - prev);
|
||||
else
|
||||
ticks -= (UINT32_MAX - prev + 1 - cur);
|
||||
ticks -= (UINT32_MAX - cur + prev);
|
||||
prev = cur;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
am33xx_platform_reset(void)
|
||||
{
|
||||
volatile uint32_t *resetaddr = (volatile uint32_t *)(KERNEL_IO_VBASE | 0x04e00f00);
|
||||
|
||||
*resetaddr = 1;
|
||||
}
|
||||
|
||||
static const struct arm_platform am33xx_platform = {
|
||||
.ap_devmap = am33xx_platform_devmap,
|
||||
.ap_init_attach_args = am33xx_platform_init_attach_args,
|
||||
.ap_bootstrap = am33xx_platform_bootstrap,
|
||||
.ap_uart_freq = am33xx_platform_uart_freq,
|
||||
.ap_delay = am33xx_platform_delay,
|
||||
.ap_reset = am33xx_platform_reset,
|
||||
};
|
||||
|
||||
void dummysetstatclockrate(int);
|
||||
void
|
||||
dummysetstatclockrate(int newhz)
|
||||
{
|
||||
}
|
||||
__weak_alias(setstatclockrate, dummysetstatclockrate);
|
||||
|
||||
ARM_PLATFORM(am33xx, "ti,am33xx", &am33xx_platform);
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: am3_prcm.c,v 1.1 2017/10/26 23:28:15 jmcneill Exp $ */
|
||||
/* $NetBSD: am3_prcm.c,v 1.1.10.1 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
|
||||
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__KERNEL_RCSID(1, "$NetBSD: am3_prcm.c,v 1.1 2017/10/26 23:28:15 jmcneill Exp $");
|
||||
__KERNEL_RCSID(1, "$NetBSD: am3_prcm.c,v 1.1.10.1 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -52,6 +52,19 @@ __KERNEL_RCSID(1, "$NetBSD: am3_prcm.c,v 1.1 2017/10/26 23:28:15 jmcneill Exp $"
|
|||
#define AM3_PRCM_CLKCTRL_MODULEMODE __BITS(1,0)
|
||||
#define AM3_PRCM_CLKCTRL_MODULEMODE_ENABLE 0x2
|
||||
|
||||
#define AM3_PRCM_CM_IDLEST_DPLL_DISP (AM3_PRCM_CM_WKUP + 0x48)
|
||||
#define AM3_PRCM_CM_IDLEST_DPLL_DISP_ST_MN_BYPASS __BIT(8)
|
||||
#define AM3_PRCM_CM_IDLEST_DPLL_DISP_ST_DPLL_CLK __BIT(0)
|
||||
#define AM3_PRCM_CM_CLKSEL_DPLL_DISP (AM3_PRCM_CM_WKUP + 0x54)
|
||||
#define AM3_PRCM_CM_CLKSEL_DPLL_DISP_DPLL_MULT __BITS(18,8)
|
||||
#define AM3_PRCM_CM_CLKSEL_DPLL_DISP_DPLL_DIV __BITS(6,0)
|
||||
#define AM3_PRCM_CM_CLKMODE_DPLL_DISP (AM3_PRCM_CM_WKUP + 0x98)
|
||||
#define AM3_PRCM_CM_CLKMODE_DPLL_DISP_DPLL_EN __BITS(2,0)
|
||||
#define AM3_PRCM_CM_CLKMODE_DPLL_DISP_DPLL_EN_MN_BYPASS 4
|
||||
#define AM3_PRCM_CM_CLKMODE_DPLL_DISP_DPLL_EN_LOCK 7
|
||||
|
||||
#define DPLL_DISP_RATE 297000000
|
||||
|
||||
static int am3_prcm_match(device_t, cfdata_t, void *);
|
||||
static void am3_prcm_attach(device_t, device_t, void *);
|
||||
|
||||
|
@ -70,8 +83,48 @@ am3_prcm_hwmod_enable(struct ti_prcm_softc *sc, struct ti_prcm_clk *tc, int enab
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
am3_prcm_hwmod_enable_display(struct ti_prcm_softc *sc, struct ti_prcm_clk *tc, int enable)
|
||||
{
|
||||
uint32_t val;
|
||||
int retry;
|
||||
|
||||
if (enable) {
|
||||
/* Put the DPLL in MN bypass mode */
|
||||
PRCM_WRITE(sc, AM3_PRCM_CM_CLKMODE_DPLL_DISP,
|
||||
__SHIFTIN(AM3_PRCM_CM_CLKMODE_DPLL_DISP_DPLL_EN_MN_BYPASS,
|
||||
AM3_PRCM_CM_CLKMODE_DPLL_DISP_DPLL_EN));
|
||||
for (retry = 10000; retry > 0; retry--) {
|
||||
val = PRCM_READ(sc, AM3_PRCM_CM_IDLEST_DPLL_DISP);
|
||||
if ((val & AM3_PRCM_CM_IDLEST_DPLL_DISP_ST_MN_BYPASS) != 0)
|
||||
break;
|
||||
delay(10);
|
||||
}
|
||||
|
||||
/* Set DPLL frequency to DPLL_DISP_RATE (297 MHz) */
|
||||
val = __SHIFTIN(DPLL_DISP_RATE / 1000000, AM3_PRCM_CM_CLKSEL_DPLL_DISP_DPLL_MULT);
|
||||
val |= __SHIFTIN(24 - 1, AM3_PRCM_CM_CLKSEL_DPLL_DISP_DPLL_DIV);
|
||||
PRCM_WRITE(sc, AM3_PRCM_CM_CLKSEL_DPLL_DISP, val);
|
||||
|
||||
/* Disable MN bypass mode */
|
||||
PRCM_WRITE(sc, AM3_PRCM_CM_CLKMODE_DPLL_DISP,
|
||||
__SHIFTIN(AM3_PRCM_CM_CLKMODE_DPLL_DISP_DPLL_EN_LOCK,
|
||||
AM3_PRCM_CM_CLKMODE_DPLL_DISP_DPLL_EN));
|
||||
for (retry = 10000; retry > 0; retry--) {
|
||||
val = PRCM_READ(sc, AM3_PRCM_CM_IDLEST_DPLL_DISP);
|
||||
if ((val & AM3_PRCM_CM_IDLEST_DPLL_DISP_ST_DPLL_CLK) != 0)
|
||||
break;
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
return am3_prcm_hwmod_enable(sc, tc, enable);
|
||||
}
|
||||
|
||||
#define AM3_PRCM_HWMOD_PER(_name, _reg, _parent) \
|
||||
TI_PRCM_HWMOD((_name), AM3_PRCM_CM_PER + (_reg), (_parent), am3_prcm_hwmod_enable)
|
||||
#define AM3_PRCM_HWMOD_PER_DISP(_name, _reg, _parent) \
|
||||
TI_PRCM_HWMOD((_name), AM3_PRCM_CM_PER + (_reg), (_parent), am3_prcm_hwmod_enable_display)
|
||||
#define AM3_PRCM_HWMOD_WKUP(_name, _reg, _parent) \
|
||||
TI_PRCM_HWMOD((_name), AM3_PRCM_CM_WKUP + (_reg), (_parent), am3_prcm_hwmod_enable)
|
||||
|
||||
|
@ -86,8 +139,10 @@ CFATTACH_DECL_NEW(am3_prcm, sizeof(struct ti_prcm_softc),
|
|||
static struct ti_prcm_clk am3_prcm_clks[] = {
|
||||
/* XXX until we get a proper clock tree */
|
||||
TI_PRCM_FIXED("FIXED_32K", 32768),
|
||||
TI_PRCM_FIXED("FIXED_24MHZ", 24000000),
|
||||
TI_PRCM_FIXED("FIXED_48MHZ", 48000000),
|
||||
TI_PRCM_FIXED("FIXED_96MHZ", 96000000),
|
||||
TI_PRCM_FIXED("DISPLAY_CLK", DPLL_DISP_RATE),
|
||||
TI_PRCM_FIXED_FACTOR("PERIPH_CLK", 1, 1, "FIXED_48MHZ"),
|
||||
TI_PRCM_FIXED_FACTOR("MMC_CLK", 1, 1, "FIXED_96MHZ"),
|
||||
|
||||
|
@ -97,17 +152,37 @@ static struct ti_prcm_clk am3_prcm_clks[] = {
|
|||
AM3_PRCM_HWMOD_PER("uart4", 0x78, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("uart5", 0x38, "PERIPH_CLK"),
|
||||
|
||||
AM3_PRCM_HWMOD_WKUP("i2c1", 0xb8, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("i2c2", 0x48, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("i2c3", 0x44, "PERIPH_CLK"),
|
||||
|
||||
AM3_PRCM_HWMOD_WKUP("gpio1", 0x8, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("gpio2", 0xac, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("gpio3", 0xb0, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("gpio4", 0xb4, "PERIPH_CLK"),
|
||||
|
||||
AM3_PRCM_HWMOD_WKUP("timer0", 0x10, "FIXED_32K"),
|
||||
AM3_PRCM_HWMOD_PER("timer2", 0x80, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("timer3", 0x84, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("timer4", 0x88, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("timer5", 0xec, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("timer6", 0xf0, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("timer7", 0x7c, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("timer2", 0x80, "FIXED_24MHZ"),
|
||||
AM3_PRCM_HWMOD_PER("timer3", 0x84, "FIXED_24MHZ"),
|
||||
AM3_PRCM_HWMOD_PER("timer4", 0x88, "FIXED_24MHZ"),
|
||||
AM3_PRCM_HWMOD_PER("timer5", 0xec, "FIXED_24MHZ"),
|
||||
AM3_PRCM_HWMOD_PER("timer6", 0xf0, "FIXED_24MHZ"),
|
||||
AM3_PRCM_HWMOD_PER("timer7", 0x7c, "FIXED_24MHZ"),
|
||||
|
||||
AM3_PRCM_HWMOD_PER("mmc0", 0x3c, "MMC_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("mmc1", 0xf4, "MMC_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("mmc2", 0xf8, "MMC_CLK"),
|
||||
|
||||
AM3_PRCM_HWMOD_PER("tpcc", 0xbc, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("tptc0", 0x24, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("tptc1", 0xfc, "PERIPH_CLK"),
|
||||
AM3_PRCM_HWMOD_PER("tptc2", 0x100, "PERIPH_CLK"),
|
||||
|
||||
AM3_PRCM_HWMOD_PER("usb_otg_hs", 0x1c, "PERIPH_CLK"),
|
||||
|
||||
AM3_PRCM_HWMOD_PER("rng", 0x90, "PERIPH_CLK"),
|
||||
|
||||
AM3_PRCM_HWMOD_PER_DISP("lcdc", 0x18, "DISPLAY_CLK"),
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -123,6 +198,7 @@ am3_prcm_attach(device_t parent, device_t self, void *aux)
|
|||
{
|
||||
struct ti_prcm_softc * const sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
int clocks;
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_phandle = faa->faa_phandle;
|
||||
|
@ -136,4 +212,8 @@ am3_prcm_attach(device_t parent, device_t self, void *aux)
|
|||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": AM3xxx PRCM\n");
|
||||
|
||||
clocks = of_find_firstchild_byname(sc->sc_phandle, "clocks");
|
||||
if (clocks > 0)
|
||||
fdt_add_bus(self, clocks, faa);
|
||||
}
|
||||
|
|
|
@ -1,41 +1,137 @@
|
|||
# $NetBSD: files.ti,v 1.4 2018/11/21 08:55:05 skrll Exp $
|
||||
# $NetBSD: files.ti,v 1.4.4.1 2019/11/27 13:46:44 martin Exp $
|
||||
#
|
||||
|
||||
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/arm/arm_generic_dma.c
|
||||
file arch/arm/arm/bus_space_a4x.S
|
||||
|
||||
file arch/arm/ti/ti_platform.c
|
||||
file arch/arm/ti/ti_cpufreq.c soc_ti
|
||||
file arch/arm/ti/am3_platform.c soc_am33xx
|
||||
file arch/arm/ti/omap3_platform.c soc_omap3
|
||||
|
||||
# Interrupt controller
|
||||
device omapintc: pic, pic_splfuncs
|
||||
attach omapintc at fdt
|
||||
file arch/arm/ti/ti_omapintc.c omapintc
|
||||
file arch/arm/ti/ti_omapintc.c omapintc
|
||||
|
||||
# sysc interconnect
|
||||
device tisysc { } : fdt, ti_prcm
|
||||
attach tisysc at fdt with ti_sysc
|
||||
file arch/arm/ti/ti_sysc.c ti_sysc
|
||||
|
||||
# PRCM
|
||||
define ti_prcm
|
||||
file arch/arm/ti/ti_prcm.c ti_prcm
|
||||
|
||||
# PRCM (AM3xxx)
|
||||
device am3prcm: ti_prcm
|
||||
device am3prcm { } : fdt, ti_prcm
|
||||
attach am3prcm at fdt with am3_prcm
|
||||
file arch/arm/ti/am3_prcm.c am3_prcm
|
||||
|
||||
# CM (OMAP3)
|
||||
device omap3cm { } : fdt, ti_prcm
|
||||
attach omap3cm at fdt with omap3_cm
|
||||
file arch/arm/ti/omap3_cm.c omap3_cm
|
||||
|
||||
# PRM (OMAP3)
|
||||
device omap3prm { } : fdt
|
||||
attach omap3prm at fdt with omap3_prm
|
||||
file arch/arm/ti/omap3_prm.c omap3_prm
|
||||
|
||||
# Clocks
|
||||
device timuxclk
|
||||
attach timuxclk at fdt with ti_mux_clock
|
||||
file arch/arm/ti/ti_mux_clock.c ti_mux_clock
|
||||
|
||||
device tidivclk
|
||||
attach tidivclk at fdt with ti_div_clock
|
||||
file arch/arm/ti/ti_div_clock.c ti_div_clock
|
||||
|
||||
device tidpllclk
|
||||
attach tidpllclk at fdt with ti_dpll_clock
|
||||
file arch/arm/ti/ti_dpll_clock.c ti_dpll_clock
|
||||
|
||||
# UART
|
||||
attach com at fdt with ti_com
|
||||
file arch/arm/ti/ti_com.c ti_com needs-flag
|
||||
attach com at fdt with ti_com: ti_prcm
|
||||
file arch/arm/ti/ti_com.c ti_com needs-flag
|
||||
|
||||
# Timer
|
||||
device omaptimer
|
||||
attach omaptimer at fdt
|
||||
file arch/arm/ti/ti_omaptimer.c omaptimer
|
||||
|
||||
# GPIO
|
||||
device tigpio: gpiobus
|
||||
attach tigpio at fdt with ti_gpio
|
||||
file arch/arm/ti/ti_gpio.c ti_gpio
|
||||
|
||||
# I2C
|
||||
device tiiic: i2cbus, i2cexec
|
||||
attach tiiic at fdt with ti_iic
|
||||
file arch/arm/ti/ti_iic.c ti_iic
|
||||
|
||||
# Ethernet
|
||||
device cpsw: ether, ifnet, arp, mii, mii_phy
|
||||
attach cpsw at fdt
|
||||
file arch/arm/ti/if_cpsw.c cpsw
|
||||
file arch/arm/ti/if_cpsw.c cpsw
|
||||
|
||||
# EDMA
|
||||
device tiedma
|
||||
attach tiedma at fdt with ti_edma
|
||||
file arch/arm/ti/ti_edma.c ti_edma
|
||||
device titptc
|
||||
attach titptc at fdt with ti_tptc
|
||||
file arch/arm/ti/ti_tptc.c ti_tptc
|
||||
|
||||
# MMCHS
|
||||
attach sdhc at fdt with ti_sdhc: ti_edma, ti_prcm
|
||||
file arch/arm/ti/ti_sdhc.c ti_sdhc
|
||||
|
||||
# USB
|
||||
device tiotg { } : fdt
|
||||
attach tiotg at fdt with ti_otg
|
||||
file arch/arm/ti/ti_otg.c ti_otg
|
||||
|
||||
device tiusb { } : fdt
|
||||
attach tiusb at fdt with ti_usb
|
||||
file arch/arm/ti/ti_usb.c ti_usb
|
||||
|
||||
device tiusbtll
|
||||
attach tiusbtll at fdt with ti_usbtll
|
||||
file arch/arm/ti/ti_usbtll.c ti_usbtll
|
||||
|
||||
attach ehci at fdt with ti_ehci
|
||||
file arch/arm/ti/ti_ehci.c ti_ehci
|
||||
|
||||
attach motg at fdt with ti_motg
|
||||
file arch/arm/ti/ti_motg.c ti_motg
|
||||
|
||||
# RNG
|
||||
device tirng
|
||||
attach tirng at fdt with ti_rng
|
||||
file arch/arm/ti/ti_rng.c ti_rng
|
||||
|
||||
# Display adapter
|
||||
device omapfb: rasops16, rasops8, wsemuldisplaydev, vcons, edid
|
||||
attach omapfb at fdt with omap3_dss
|
||||
file arch/arm/ti/omap3_dss.c omap3_dss
|
||||
|
||||
define tilcdcfbbus { }
|
||||
device tilcdc: drmkms, tilcdcfbbus
|
||||
attach tilcdc at fdt with ti_lcdc
|
||||
file arch/arm/ti/ti_lcdc.c ti_lcdc
|
||||
|
||||
device tifb: tilcdcfbbus, drmfb, wsemuldisplaydev
|
||||
attach tifb at tilcdcfbbus with ti_fb
|
||||
file arch/arm/ti/ti_fb.c ti_fb
|
||||
|
||||
# Memory controller
|
||||
device tigpmc { } : fdt
|
||||
attach tigpmc at fdt with ti_gpmc
|
||||
file arch/arm/ti/ti_gpmc.c ti_gpmc
|
||||
|
||||
# NAND flash controller
|
||||
device omapnand: nandbus
|
||||
attach omapnand at fdt
|
||||
file arch/arm/ti/omap2_nand.c omapnand
|
||||
|
||||
# SOC parameters
|
||||
defflag opt_soc.h SOC_TI
|
||||
defflag opt_soc.h SOC_AM33XX: SOC_TI
|
||||
defflag opt_soc.h SOC_OMAP3: SOC_TI
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_cpsw.c,v 1.6 2019/05/29 06:17:27 msaitoh Exp $ */
|
||||
/* $NetBSD: if_cpsw.c,v 1.6.2.1 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 Jonathan A. Kollasch
|
||||
|
@ -53,7 +53,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(1, "$NetBSD: if_cpsw.c,v 1.6 2019/05/29 06:17:27 msaitoh Exp $");
|
||||
__KERNEL_RCSID(1, "$NetBSD: if_cpsw.c,v 1.6.2.1 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -73,14 +73,11 @@ __KERNEL_RCSID(1, "$NetBSD: if_cpsw.c,v 1.6 2019/05/29 06:17:27 msaitoh Exp $");
|
|||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
|
||||
#if 0
|
||||
#include <arch/arm/omap/omap2_obiovar.h>
|
||||
#else
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
#endif
|
||||
#include <arch/arm/omap/if_cpswreg.h>
|
||||
#include <arch/arm/omap/sitara_cmreg.h>
|
||||
#include <arch/arm/omap/sitara_cm.h>
|
||||
|
||||
#include <arm/ti/if_cpswreg.h>
|
||||
|
||||
#define FDT_INTR_FLAGS 0
|
||||
|
||||
#define CPSW_TXFRAGS 16
|
||||
|
||||
|
@ -398,14 +395,14 @@ cpsw_attach(device_t parent, device_t self, void *aux)
|
|||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
struct cpsw_softc * const sc = device_private(self);
|
||||
prop_dictionary_t dict = device_properties(self);
|
||||
struct ethercom * const ec = &sc->sc_ec;
|
||||
struct ifnet * const ifp = &ec->ec_if;
|
||||
struct mii_data * const mii = &sc->sc_mii;
|
||||
const int phandle = faa->faa_phandle;
|
||||
const uint8_t *macaddr;
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
int error;
|
||||
int error, slave, len;
|
||||
u_int i;
|
||||
|
||||
KERNHIST_INIT(cpswhist, 4096);
|
||||
|
@ -423,8 +420,14 @@ cpsw_attach(device_t parent, device_t self, void *aux)
|
|||
callout_init(&sc->sc_tick_ch, 0);
|
||||
callout_setfunc(&sc->sc_tick_ch, cpsw_tick, sc);
|
||||
|
||||
prop_data_t eaprop = prop_dictionary_get(dict, "mac-address");
|
||||
if (eaprop == NULL) {
|
||||
macaddr = NULL;
|
||||
slave = of_find_firstchild_byname(phandle, "slave");
|
||||
if (slave > 0) {
|
||||
macaddr = fdtbus_get_prop(slave, "mac-address", &len);
|
||||
if (len != ETHER_ADDR_LEN)
|
||||
macaddr = NULL;
|
||||
}
|
||||
if (macaddr == NULL) {
|
||||
#if 0
|
||||
/* grab mac_id0 from AM335x control module */
|
||||
uint32_t reg_lo, reg_hi;
|
||||
|
@ -461,28 +464,13 @@ cpsw_attach(device_t parent, device_t self, void *aux)
|
|||
#endif
|
||||
}
|
||||
} else {
|
||||
KASSERT(prop_object_type(eaprop) == PROP_TYPE_DATA);
|
||||
KASSERT(prop_data_size(eaprop) == ETHER_ADDR_LEN);
|
||||
memcpy(sc->sc_enaddr, prop_data_data_nocopy(eaprop),
|
||||
ETHER_ADDR_LEN);
|
||||
memcpy(sc->sc_enaddr, macaddr, ETHER_ADDR_LEN);
|
||||
}
|
||||
|
||||
#if 0
|
||||
sc->sc_rxthih = intr_establish(oa->obio_intrbase + CPSW_INTROFF_RXTH,
|
||||
IPL_VM, IST_LEVEL, cpsw_rxthintr, sc);
|
||||
sc->sc_rxih = intr_establish(oa->obio_intrbase + CPSW_INTROFF_RX,
|
||||
IPL_VM, IST_LEVEL, cpsw_rxintr, sc);
|
||||
sc->sc_txih = intr_establish(oa->obio_intrbase + CPSW_INTROFF_TX,
|
||||
IPL_VM, IST_LEVEL, cpsw_txintr, sc);
|
||||
sc->sc_miscih = intr_establish(oa->obio_intrbase + CPSW_INTROFF_MISC,
|
||||
IPL_VM, IST_LEVEL, cpsw_miscintr, sc);
|
||||
#else
|
||||
#define FDT_INTR_FLAGS 0
|
||||
sc->sc_rxthih = fdtbus_intr_establish(phandle, CPSW_INTROFF_RXTH, IPL_VM, FDT_INTR_FLAGS, cpsw_rxthintr, sc);
|
||||
sc->sc_rxih = fdtbus_intr_establish(phandle, CPSW_INTROFF_RX, IPL_VM, FDT_INTR_FLAGS, cpsw_rxintr, sc);
|
||||
sc->sc_txih = fdtbus_intr_establish(phandle, CPSW_INTROFF_TX, IPL_VM, FDT_INTR_FLAGS, cpsw_txintr, sc);
|
||||
sc->sc_miscih = fdtbus_intr_establish(phandle, CPSW_INTROFF_MISC, IPL_VM, FDT_INTR_FLAGS, cpsw_miscintr, sc);
|
||||
#endif
|
||||
|
||||
sc->sc_bst = faa->faa_bst;
|
||||
sc->sc_bss = size;
|
||||
|
@ -587,19 +575,6 @@ cpsw_attach(device_t parent, device_t self, void *aux)
|
|||
ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_MANUAL);
|
||||
} else {
|
||||
sc->sc_phy_has_1000t = cpsw_phy_has_1000t(sc);
|
||||
if (sc->sc_phy_has_1000t) {
|
||||
#if 0
|
||||
aprint_normal_dev(sc->sc_dev, "1000baseT PHY found. "
|
||||
"Setting RGMII Mode\n");
|
||||
/*
|
||||
* Select the Interface RGMII Mode in the Control
|
||||
* Module
|
||||
*/
|
||||
sitara_cm_reg_write_4(CPSW_GMII_SEL,
|
||||
GMIISEL_GMII2_SEL(RGMII_MODE) |
|
||||
GMIISEL_GMII1_SEL(RGMII_MODE));
|
||||
#endif
|
||||
}
|
||||
|
||||
ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
/*-
|
||||
* Copyright (c) 2012 Damjan Marion <dmarion@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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _IF_CPSWREG_H
|
||||
#define _IF_CPSWREG_H
|
||||
|
||||
#define CPSW_ETH_PORTS 2
|
||||
#define CPSW_CPPI_PORTS 1
|
||||
|
||||
#define CPSW_SS_OFFSET 0x0000
|
||||
#define CPSW_SS_IDVER (CPSW_SS_OFFSET + 0x00)
|
||||
#define CPSW_SS_SOFT_RESET (CPSW_SS_OFFSET + 0x08)
|
||||
#define CPSW_SS_STAT_PORT_EN (CPSW_SS_OFFSET + 0x0C)
|
||||
#define CPSW_SS_PTYPE (CPSW_SS_OFFSET + 0x10)
|
||||
#define CPSW_SS_FLOW_CONTROL (CPSW_SS_OFFSET + 0x24)
|
||||
#define CPSW_SS_RGMII_CTL (CPSW_SS_OFFSET + 0x88)
|
||||
|
||||
#define CPSW_PORT_OFFSET 0x0100
|
||||
#define CPSW_PORT_P_TX_PRI_MAP(p) (CPSW_PORT_OFFSET + 0x118 + ((p-1) * 0x100))
|
||||
#define CPSW_PORT_P0_CPDMA_TX_PRI_MAP (CPSW_PORT_OFFSET + 0x01C)
|
||||
#define CPSW_PORT_P0_CPDMA_RX_CH_MAP (CPSW_PORT_OFFSET + 0x020)
|
||||
#define CPSW_PORT_P_SA_LO(p) (CPSW_PORT_OFFSET + 0x120 + ((p-1) * 0x100))
|
||||
#define CPSW_PORT_P_SA_HI(p) (CPSW_PORT_OFFSET + 0x124 + ((p-1) * 0x100))
|
||||
|
||||
#define CPSW_GMII_SEL 0x0650
|
||||
|
||||
#define CPSW_CPDMA_OFFSET 0x0800
|
||||
#define CPSW_CPDMA_TX_CONTROL (CPSW_CPDMA_OFFSET + 0x04)
|
||||
#define CPSW_CPDMA_TX_TEARDOWN (CPSW_CPDMA_OFFSET + 0x08)
|
||||
#define CPSW_CPDMA_RX_CONTROL (CPSW_CPDMA_OFFSET + 0x14)
|
||||
#define CPSW_CPDMA_RX_TEARDOWN (CPSW_CPDMA_OFFSET + 0x18)
|
||||
#define CPSW_CPDMA_SOFT_RESET (CPSW_CPDMA_OFFSET + 0x1c)
|
||||
#define CPSW_CPDMA_DMACONTROL (CPSW_CPDMA_OFFSET + 0x20)
|
||||
#define CPSW_CPDMA_DMASTATUS (CPSW_CPDMA_OFFSET + 0x24)
|
||||
#define CPSW_CPDMA_RX_BUFFER_OFFSET (CPSW_CPDMA_OFFSET + 0x28)
|
||||
#define CPSW_CPDMA_TX_INTSTAT_RAW (CPSW_CPDMA_OFFSET + 0x80)
|
||||
#define CPSW_CPDMA_TX_INTSTAT_MASKED (CPSW_CPDMA_OFFSET + 0x84)
|
||||
#define CPSW_CPDMA_TX_INTMASK_SET (CPSW_CPDMA_OFFSET + 0x88)
|
||||
#define CPSW_CPDMA_TX_INTMASK_CLEAR (CPSW_CPDMA_OFFSET + 0x8C)
|
||||
#define CPSW_CPDMA_CPDMA_EOI_VECTOR (CPSW_CPDMA_OFFSET + 0x94)
|
||||
#define CPSW_CPDMA_RX_INTSTAT_RAW (CPSW_CPDMA_OFFSET + 0xA0)
|
||||
#define CPSW_CPDMA_RX_INTSTAT_MASKED (CPSW_CPDMA_OFFSET + 0xA4)
|
||||
#define CPSW_CPDMA_RX_INTMASK_SET (CPSW_CPDMA_OFFSET + 0xA8)
|
||||
#define CPSW_CPDMA_RX_INTMASK_CLEAR (CPSW_CPDMA_OFFSET + 0xAc)
|
||||
#define CPSW_CPDMA_DMA_INTSTAT_RAW (CPSW_CPDMA_OFFSET + 0xB0)
|
||||
#define CPSW_CPDMA_DMA_INTSTAT_MASKED (CPSW_CPDMA_OFFSET + 0xB4)
|
||||
#define CPSW_CPDMA_DMA_INTMASK_SET (CPSW_CPDMA_OFFSET + 0xB8)
|
||||
#define CPSW_CPDMA_DMA_INTMASK_CLEAR (CPSW_CPDMA_OFFSET + 0xBC)
|
||||
#define CPSW_CPDMA_RX_FREEBUFFER(p) (CPSW_CPDMA_OFFSET + 0x0e0 + ((p) * 0x04))
|
||||
|
||||
#define CPSW_STATS_OFFSET 0x0900
|
||||
|
||||
#define CPSW_STATERAM_OFFSET 0x0A00
|
||||
#define CPSW_CPDMA_TX_HDP(p) (CPSW_STATERAM_OFFSET + 0x00 + ((p) * 0x04))
|
||||
#define CPSW_CPDMA_RX_HDP(p) (CPSW_STATERAM_OFFSET + 0x20 + ((p) * 0x04))
|
||||
#define CPSW_CPDMA_TX_CP(p) (CPSW_STATERAM_OFFSET + 0x40 + ((p) * 0x04))
|
||||
#define CPSW_CPDMA_RX_CP(p) (CPSW_STATERAM_OFFSET + 0x60 + ((p) * 0x04))
|
||||
|
||||
#define CPSW_CPTS_OFFSET 0x0C00
|
||||
|
||||
#define CPSW_ALE_OFFSET 0x0D00
|
||||
#define CPSW_ALE_CONTROL (CPSW_ALE_OFFSET + 0x08)
|
||||
#define CPSW_ALE_TBLCTL (CPSW_ALE_OFFSET + 0x20)
|
||||
#define CPSW_ALE_TBLW2 (CPSW_ALE_OFFSET + 0x34)
|
||||
#define CPSW_ALE_TBLW1 (CPSW_ALE_OFFSET + 0x38)
|
||||
#define CPSW_ALE_TBLW0 (CPSW_ALE_OFFSET + 0x3C)
|
||||
#define CPSW_ALE_PORTCTL(p) (CPSW_ALE_OFFSET + 0x40 + ((p) * 0x04))
|
||||
|
||||
#define CPSW_SL_OFFSET 0x0D80
|
||||
#define CPSW_SL_IDVER(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x00)
|
||||
#define CPSW_SL_MACCONTROL(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x04)
|
||||
#define CPSW_SL_MACSTATUS(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x08)
|
||||
#define CPSW_SL_SOFT_RESET(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x0C)
|
||||
#define CPSW_SL_RX_MAXLEN(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x10)
|
||||
#define CPSW_SL_BOFFTEST(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x14)
|
||||
#define CPSW_SL_RX_PAUSE(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x18)
|
||||
#define CPSW_SL_TX_PAUSE(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x1C)
|
||||
#define CPSW_SL_EMCONTROL(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x20)
|
||||
#define CPSW_SL_RX_PRI_MAP(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x24)
|
||||
#define CPSW_SL_TX_GAP(p) (CPSW_SL_OFFSET + (0x40 * (p)) + 0x28)
|
||||
|
||||
#define MDIO_OFFSET 0x1000
|
||||
#define MDIOCONTROL (MDIO_OFFSET + 0x04)
|
||||
#define MDIOUSERACCESS0 (MDIO_OFFSET + 0x80)
|
||||
#define MDIOUSERPHYSEL0 (MDIO_OFFSET + 0x84)
|
||||
|
||||
#define CPSW_WR_OFFSET 0x1200
|
||||
#define CPSW_WR_SOFT_RESET (CPSW_WR_OFFSET + 0x04)
|
||||
#define CPSW_WR_CONTROL (CPSW_WR_OFFSET + 0x08)
|
||||
#define CPSW_WR_INT_CONTROL (CPSW_WR_OFFSET + 0x0c)
|
||||
#define CPSW_WR_C_RX_THRESH_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x10)
|
||||
#define CPSW_WR_C_RX_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x14)
|
||||
#define CPSW_WR_C_TX_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x18)
|
||||
#define CPSW_WR_C_MISC_EN(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x1C)
|
||||
#define CPSW_WR_C_RX_THRESH_STAT(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x40)
|
||||
#define CPSW_WR_C_RX_STAT(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x44)
|
||||
#define CPSW_WR_C_TX_STAT(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x48)
|
||||
#define CPSW_WR_C_MISC_STAT(p) (CPSW_WR_OFFSET + (0x10 * (p)) + 0x4C)
|
||||
|
||||
#define CPSW_CPPI_RAM_OFFSET 0x2000
|
||||
|
||||
|
||||
#define __BIT32(x) ((uint32_t)__BIT(x))
|
||||
#define __BITS32(x, y) ((uint32_t)__BITS((x), (y)))
|
||||
|
||||
/* flags for descriptor word 3 */
|
||||
#define CPDMA_BD_SOP __BIT32(31)
|
||||
#define CPDMA_BD_EOP __BIT32(30)
|
||||
#define CPDMA_BD_OWNER __BIT32(29)
|
||||
#define CPDMA_BD_EOQ __BIT32(28)
|
||||
#define CPDMA_BD_TDOWNCMPLT __BIT32(27)
|
||||
#define CPDMA_BD_PASSCRC __BIT32(26)
|
||||
|
||||
#define CPDMA_BD_LONG __BIT32(25) /* Rx descriptor only */
|
||||
#define CPDMA_BD_SHORT __BIT32(24)
|
||||
#define CPDMA_BD_MAC_CTL __BIT32(23)
|
||||
#define CPDMA_BD_OVERRUN __BIT32(22)
|
||||
#define CPDMA_BD_PKT_ERR_MASK __BITS32(21,20)
|
||||
#define CPDMA_BD_RX_VLAN_ENCAP __BIT32(19)
|
||||
#define CPDMA_BD_FROM_PORT __BITS32(18,16)
|
||||
|
||||
#define CPDMA_BD_TO_PORT_EN __BIT32(20) /* Tx descriptor only */
|
||||
#define CPDMA_BD_TO_PORT __BITS32(17,16)
|
||||
|
||||
struct cpsw_cpdma_bd {
|
||||
uint32_t word[4];
|
||||
} __packed __aligned(4);
|
||||
|
||||
/* Interrupt offsets */
|
||||
#define CPSW_INTROFF_RXTH 0
|
||||
#define CPSW_INTROFF_RX 1
|
||||
#define CPSW_INTROFF_TX 2
|
||||
#define CPSW_INTROFF_MISC 3
|
||||
|
||||
/* MDIOCONTROL Register Field */
|
||||
#define MDIOCTL_IDLE __BIT32(31)
|
||||
#define MDIOCTL_ENABLE __BIT32(30)
|
||||
#define MDIOCTL_HIGHEST_USER_CHANNEL(val) ((0xf & (val)) << 24)
|
||||
#define MDIOCTL_PREAMBLE __BIT32(20)
|
||||
#define MDIOCTL_FAULT __BIT32(19)
|
||||
#define MDIOCTL_FAULTENB __BIT32(18)
|
||||
#define MDIOCTL_INTTESTENB __BIT32(17)
|
||||
#define MDIOCTL_CLKDIV(val) (0xff & (val))
|
||||
|
||||
/* ALE Control Register Field */
|
||||
#define ALECTL_ENABLE_ALE __BIT32(31)
|
||||
#define ALECTL_CLEAR_TABLE __BIT32(30)
|
||||
#define ALECTL_AGE_OUT_NOW __BIT32(29)
|
||||
#define ALECTL_EN_P0_UNI_FLOOD __BIT32(8)
|
||||
#define ALECTL_LEARN_NO_VID __BIT32(7)
|
||||
#define ALECTL_EN_VID0_MODE __BIT32(6)
|
||||
#define ALECTL_ENABLE_OUI_DENY __BIT32(5)
|
||||
#define ALECTL_BYPASS __BIT32(4)
|
||||
#define ALECTL_RATE_LIMIT_TX __BIT32(3)
|
||||
#define ALECTL_VLAN_AWARE __BIT32(2)
|
||||
#define ALECTL_ENABLE_AUTH_MODE __BIT32(1)
|
||||
#define ALECTL_ENABLE_RATE_LIMIT __BIT32(0)
|
||||
|
||||
/* GMII_SEL Register Field */
|
||||
#define GMIISEL_RMII2_IO_CLK_EN __BIT32(7)
|
||||
#define GMIISEL_RMII1_IO_CLK_EN __BIT32(6)
|
||||
#define GMIISEL_RGMII2_IDMODE __BIT32(5)
|
||||
#define GMIISEL_RGMII1_IDMODE __BIT32(4)
|
||||
#define GMIISEL_GMII2_SEL(val) ((0x3 & (val)) << 2)
|
||||
#define GMIISEL_GMII1_SEL(val) ((0x3 & (val)) << 0)
|
||||
#define GMII_MODE 0
|
||||
#define RMII_MODE 1
|
||||
#define RGMII_MODE 2
|
||||
|
||||
/* Sliver MACCONTROL Register Field */
|
||||
#define SLMACCTL_RX_CMF_EN __BIT32(24)
|
||||
#define SLMACCTL_RX_CSF_EN __BIT32(23)
|
||||
#define SLMACCTL_RX_CEF_EN __BIT32(22)
|
||||
#define SLMACCTL_TX_SHORT_GAP_LIM_EN __BIT32(21)
|
||||
#define SLMACCTL_EXT_EN __BIT32(18)
|
||||
#define SLMACCTL_GIG_FORCE __BIT32(17)
|
||||
#define SLMACCTL_IFCTL_B __BIT32(16)
|
||||
#define SLMACCTL_IFCTL_A __BIT32(15)
|
||||
#define SLMACCTL_CMD_IDLE __BIT32(11)
|
||||
#define SLMACCTL_TX_SHORT_GAP_EN __BIT32(10)
|
||||
#define SLMACCTL_GIG __BIT32(7)
|
||||
#define SLMACCTL_TX_PACE __BIT32(6)
|
||||
#define SLMACCTL_GMII_EN __BIT32(5)
|
||||
#define SLMACCTL_TX_FLOW_EN __BIT32(4)
|
||||
#define SLMACCTL_RX_FLOW_EN __BIT32(3)
|
||||
#define SLMACCTL_MTEST __BIT32(2)
|
||||
#define SLMACCTL_LOOPBACK __BIT32(1)
|
||||
#define SLMACCTL_FULLDUPLEX __BIT32(0)
|
||||
|
||||
/* ALE Address Table Entry Field */
|
||||
typedef enum {
|
||||
ALE_ENTRY_TYPE,
|
||||
ALE_MCAST_FWD_STATE,
|
||||
ALE_PORT_MASK,
|
||||
ALE_PORT_NUMBER,
|
||||
} ale_entry_field_t;
|
||||
|
||||
#define ALE_TYPE_FREE 0
|
||||
#define ALE_TYPE_ADDRESS 1
|
||||
#define ALE_TYPE_VLAN 2
|
||||
#define ALE_TYPE_VLAN_ADDRESS 3
|
||||
|
||||
/*
|
||||
* The port state(s) required for the received port on a destination address lookup
|
||||
* in order for the multicast packet to be forwarded to the transmit port(s)
|
||||
*/
|
||||
#define ALE_FWSTATE_ALL 1 /* Blocking/Forwarding/Learning */
|
||||
#define ALE_FWSTATE_NOBLOCK 2 /* Forwarding/Learning */
|
||||
#define ALE_FWSTATE_FWONLY 3 /* Forwarding */
|
||||
|
||||
#define ALE_PORT_MASK_ALL 7
|
||||
|
||||
#endif /*_IF_CPSWREG_H */
|
|
@ -0,0 +1,236 @@
|
|||
/* $NetBSD: omap2_gpmcreg.h,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2007 Microsoft
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Microsoft
|
||||
*
|
||||
* 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 OR CONTRIBUTERS 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 _OMAP2430GPMCREG_H
|
||||
#define _OMAP2430GPMCREG_H
|
||||
|
||||
/*
|
||||
* Header for OMAP2 General Purpose Memory Controller
|
||||
*/
|
||||
|
||||
#define GPMC_REVISION 0x000
|
||||
#define GPMC_SYSCONFIG 0x010
|
||||
#define GPMC_SYSSTATUS 0x014
|
||||
#define GPMC_IRQSTATUS 0x018
|
||||
#define GPMC_IRQENABLE 0x01C
|
||||
#define GPMC_TIMEOUT_CONTROL 0x040
|
||||
#define GPMC_ERR_ADDRESS 0x044
|
||||
#define GPMC_ERR_TYPE 0x048
|
||||
#define GPMC_CONFIG 0x050
|
||||
#define GPMC_STATUS 0x054
|
||||
#define GPMC_CONFIG1_0 0x060
|
||||
#define GPMC_CONFIG2_0 0x064
|
||||
#define GPMC_CONFIG3_0 0x068
|
||||
#define GPMC_CONFIG4_0 0x06C
|
||||
#define GPMC_CONFIG5_0 0x070
|
||||
#define GPMC_CONFIG6_0 0x074
|
||||
#define GPMC_CONFIG7_0 0x078
|
||||
#define GPMC_NAND_COMMAND_0 0x07C
|
||||
#define GPMC_NAND_ADDRESS_0 0x080
|
||||
#define GPMC_NAND_DATA_0 0x084
|
||||
#define GPMC_CONFIG1_1 0x090
|
||||
#define GPMC_CONFIG2_1 0x094
|
||||
#define GPMC_CONFIG3_1 0x098
|
||||
#define GPMC_CONFIG4_1 0x09C
|
||||
#define GPMC_CONFIG5_1 0x0A0
|
||||
#define GPMC_CONFIG6_1 0x0A4
|
||||
#define GPMC_CONFIG7_1 0x0A8
|
||||
#define GPMC_NAND_COMMAND_1 0x0AC
|
||||
#define GPMC_NAND_ADDRESS_1 0x0B0
|
||||
#define GPMC_NAND_DATA_1 0x0B4
|
||||
#define GPMC_CONFIG1_2 0x0C0
|
||||
#define GPMC_CONFIG2_2 0x0C4
|
||||
#define GPMC_CONFIG3_2 0x0C8
|
||||
#define GPMC_CONFIG4_2 0x0CC
|
||||
#define GPMC_CONFIG5_2 0x0D0
|
||||
#define GPMC_CONFIG6_2 0x0D4
|
||||
#define GPMC_CONFIG7_2 0x0D8
|
||||
#define GPMC_NAND_COMMAND_2 0x0DC
|
||||
#define GPMC_NAND_ADDRESS_2 0x0E0
|
||||
#define GPMC_NAND_DATA_2 0x0E4
|
||||
#define GPMC_CONFIG1_3 0x0F0
|
||||
#define GPMC_CONFIG2_3 0x0F4
|
||||
#define GPMC_CONFIG3_3 0x0F8
|
||||
#define GPMC_CONFIG4_3 0x0FC
|
||||
#define GPMC_CONFIG5_3 0x100
|
||||
#define GPMC_CONFIG6_3 0x104
|
||||
#define GPMC_CONFIG7_3 0x108
|
||||
#define GPMC_NAND_COMMAND_3 0x10C
|
||||
#define GPMC_NAND_ADDRESS_3 0x110
|
||||
#define GPMC_NAND_DATA_3 0x114
|
||||
#define GPMC_CONFIG1_4 0x120
|
||||
#define GPMC_CONFIG2_4 0x124
|
||||
#define GPMC_CONFIG3_4 0x128
|
||||
#define GPMC_CONFIG4_4 0x12C
|
||||
#define GPMC_CONFIG5_4 0x130
|
||||
#define GPMC_CONFIG6_4 0x134
|
||||
#define GPMC_CONFIG7_4 0x138
|
||||
#define GPMC_NAND_COMMAND_4 0x13C
|
||||
#define GPMC_NAND_ADDRESS_4 0x140
|
||||
#define GPMC_NAND_DATA_4 0x144
|
||||
#define GPMC_CONFIG1_5 0x150
|
||||
#define GPMC_CONFIG2_5 0x154
|
||||
#define GPMC_CONFIG3_5 0x158
|
||||
#define GPMC_CONFIG4_5 0x15C
|
||||
#define GPMC_CONFIG5_5 0x160
|
||||
#define GPMC_CONFIG6_5 0x164
|
||||
#define GPMC_CONFIG7_5 0x168
|
||||
#define GPMC_NAND_COMMAND_5 0x16C
|
||||
#define GPMC_NAND_ADDRESS_5 0x170
|
||||
#define GPMC_NAND_DATA_5 0x174
|
||||
#define GPMC_CONFIG1_6 0x180
|
||||
#define GPMC_CONFIG2_6 0x184
|
||||
#define GPMC_CONFIG3_6 0x188
|
||||
#define GPMC_CONFIG4_6 0x18C
|
||||
#define GPMC_CONFIG5_6 0x190
|
||||
#define GPMC_CONFIG6_6 0x194
|
||||
#define GPMC_CONFIG7_6 0x198
|
||||
#define GPMC_NAND_COMMAND_6 0x19C
|
||||
#define GPMC_NAND_ADDRESS_6 0x1A0
|
||||
#define GPMC_NAND_DATA_6 0x1A4
|
||||
#define GPMC_CONFIG1_7 0x1B0
|
||||
#define GPMC_CONFIG2_7 0x1B4
|
||||
#define GPMC_CONFIG3_7 0x1B8
|
||||
#define GPMC_CONFIG4_7 0x1BC
|
||||
#define GPMC_CONFIG5_7 0x1C0
|
||||
#define GPMC_CONFIG6_7 0x1C4
|
||||
#define GPMC_CONFIG7_7 0x1C8
|
||||
#define GPMC_NAND_COMMAND_7 0x1CC
|
||||
#define GPMC_NAND_ADDRESS_7 0x1D0
|
||||
#define GPMC_NAND_DATA_7 0x1D4
|
||||
#define GPMC_PREFETCH_CONFIG1 0x1E0
|
||||
#define GPMC_PREFETCH_CONFIG2 0x1E4
|
||||
#define GPMC_PREFETCH_CONTROL 0x1EC
|
||||
#define GPMC_CONFIG1_6 0x180
|
||||
#define GPMC_CONFIG2_6 0x184
|
||||
#define GPMC_CONFIG3_6 0x188
|
||||
#define GPMC_CONFIG4_6 0x18C
|
||||
#define GPMC_CONFIG5_6 0x190
|
||||
#define GPMC_CONFIG6_6 0x194
|
||||
#define GPMC_CONFIG7_6 0x198
|
||||
#define GPMC_NAND_COMMAND_6 0x19C
|
||||
#define GPMC_NAND_ADDRESS_6 0x1A0
|
||||
#define GPMC_NAND_DATA_6 0x1A4
|
||||
#define GPMC_CONFIG1_7 0x1B0
|
||||
#define GPMC_CONFIG2_7 0x1B4
|
||||
#define GPMC_CONFIG3_7 0x1B8
|
||||
#define GPMC_CONFIG4_7 0x1BC
|
||||
#define GPMC_CONFIG5_7 0x1C0
|
||||
#define GPMC_CONFIG6_7 0x1C4
|
||||
#define GPMC_CONFIG7_7 0x1C8
|
||||
#define GPMC_NAND_COMMAND_7 0x1CC
|
||||
#define GPMC_NAND_ADDRESS_7 0x1D0
|
||||
#define GPMC_NAND_DATA_7 0x1D4
|
||||
#define GPMC_PREFETCH_CONFIG1 0x1E0
|
||||
#define GPMC_PREFETCH_CONFIG2 0x1E4
|
||||
#define GPMC_PREFETCH_CONTROL 0x1EC
|
||||
#define GPMC_PREFETCH_STATUS 0x1F0
|
||||
#define GPMC_ECC_CONFIG 0x1F4
|
||||
#define GPMC_ECC_CONTROL 0x1F8
|
||||
#define GPMC_ECC_SIZE_CONFIG 0x1FC
|
||||
#define GPMC_ECC1_RESULT 0x200
|
||||
#define GPMC_ECC2_RESULT 0x204
|
||||
#define GPMC_ECC3_RESULT 0x208
|
||||
#define GPMC_ECC4_RESULT 0x20C
|
||||
#define GPMC_ECC5_RESULT 0x210
|
||||
#define GPMC_ECC6_RESULT 0x214
|
||||
#define GPMC_ECC7_RESULT 0x218
|
||||
#define GPMC_ECC8_RESULT 0x21C
|
||||
#define GPMC_ECC9_RESULT 0x220
|
||||
#define GPMC_TESTMODE_CTRL 0x230
|
||||
#define GPMC_PSA_LSB 0x234
|
||||
#define GPMC_PSA_MSB 0x238
|
||||
|
||||
#define GPMC_SIZE (GPMC_PSA_MSB + 4)
|
||||
#define GPMC_NCS 8 /* # Chip Selects */
|
||||
#define GPMC_CS_SIZE (GPMC_CONFIG1_1 - GPMC_CONFIG1_0)
|
||||
|
||||
#define GPMC_CS_CONFIG_BASE(base, cs) \
|
||||
((base) + GPMC_CONFIG1_0 + (cs) * GPMC_CS_SIZE)
|
||||
#define GPMC_CS_CONFIG(cs) \
|
||||
(GPMC_CONFIG1_0 + (cs) * GPMC_CS_SIZE)
|
||||
|
||||
#define GPMC_CONFIG1_i (GPMC_CONFIG1_0 - GPMC_CONFIG1_0)
|
||||
#define GPMC_CONFIG2_i (GPMC_CONFIG2_0 - GPMC_CONFIG1_0)
|
||||
#define GPMC_CONFIG3_i (GPMC_CONFIG3_0 - GPMC_CONFIG1_0)
|
||||
#define GPMC_CONFIG4_i (GPMC_CONFIG4_0 - GPMC_CONFIG1_0)
|
||||
#define GPMC_CONFIG5_i (GPMC_CONFIG5_0 - GPMC_CONFIG1_0)
|
||||
#define GPMC_CONFIG6_i (GPMC_CONFIG6_0 - GPMC_CONFIG1_0)
|
||||
#define GPMC_CONFIG7_i (GPMC_CONFIG7_0 - GPMC_CONFIG1_0)
|
||||
|
||||
/*
|
||||
* GPMC OMAP2430_GPMC_REVISION
|
||||
*/
|
||||
#define GPMC_REVISION_REV __BITS(7,0)
|
||||
#define GPMC_REVISION_REV_MAJ(r) (((r) >> 4) & 0xf)
|
||||
#define GPMC_REVISION_REV_MIN(r) (((r) >> 0) & 0xf)
|
||||
|
||||
/*
|
||||
* GPMC CONFIG7_[0-7] bits
|
||||
*/
|
||||
#define GPMC_CONFIG7_BASEADDRESS __BITS(5,0)
|
||||
#define GPMC_CONFIG7_CSVALID __BIT(6)
|
||||
#define GPMC_CONFIG7_MASKADDRESS __BITS(11,8)
|
||||
#define GPMC_CONFIG7(m, b) (((m) << 8) | (((b) >> 24) & 0x3f))
|
||||
#define GPMC_CONFIG7_MASK_256M 0x0
|
||||
#define GPMC_CONFIG7_MASK_128M 0x8
|
||||
#define GPMC_CONFIG7_MASK_64M 0xc
|
||||
#define GPMC_CONFIG7_MASK_32M 0xe
|
||||
#define GPMC_CONFIG7_MASK_16M 0xf
|
||||
|
||||
static __inline ulong
|
||||
omap_gpmc_config7_addr(uint32_t r)
|
||||
{
|
||||
return ((r) & GPMC_CONFIG7_BASEADDRESS) << 24;
|
||||
}
|
||||
static __inline ulong
|
||||
omap_gpmc_config7_size(uint32_t r)
|
||||
{
|
||||
uint i;
|
||||
uint mask;
|
||||
const struct {
|
||||
uint mask;
|
||||
ulong size;
|
||||
} gpmc_config7_size_tab[5] = {
|
||||
{ GPMC_CONFIG7_MASK_256M, (256 << 20) },
|
||||
{ GPMC_CONFIG7_MASK_128M, (128 << 20) },
|
||||
{ GPMC_CONFIG7_MASK_64M, ( 64 << 20) },
|
||||
{ GPMC_CONFIG7_MASK_32M, ( 32 << 20) },
|
||||
{ GPMC_CONFIG7_MASK_16M, ( 16 << 20) },
|
||||
};
|
||||
mask = ((r) & GPMC_CONFIG7_MASKADDRESS) >> 8;
|
||||
for (i=0; i < 5; i++) {
|
||||
if (gpmc_config7_size_tab[i].mask == mask)
|
||||
return gpmc_config7_size_tab[i].size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _OMAP2430GPMCREG_H */
|
|
@ -0,0 +1,535 @@
|
|||
/* $NetBSD: omap2_nand.c,v 1.2.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 Department of Software Engineering,
|
||||
* University of Szeged, Hungary
|
||||
* Copyright (c) 2010 Adam Hoka <ahoka@NetBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by the Department of Software Engineering, University of Szeged, Hungary
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Device driver for the NAND controller found in Texas Instruments OMAP2
|
||||
* and later SOCs.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: omap2_nand.c,v 1.2.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
/* TODO move to opt_* */
|
||||
#undef OMAP2_NAND_HARDWARE_ECC
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <arm/ti/omap2_gpmcreg.h>
|
||||
|
||||
#include <dev/nand/nand.h>
|
||||
#include <dev/nand/onfi.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
extern struct flash_interface nand_flash_if;
|
||||
extern int flash_print(void *, const char *);
|
||||
|
||||
/* GPMC_STATUS */
|
||||
#define WAIT0 __BIT(8) /* active low */
|
||||
|
||||
/* GPMC_ECC_CONTROL */
|
||||
#define ECCCLEAR __BIT(8)
|
||||
#define ECCPOINTER __BITS(3,0)
|
||||
|
||||
/* GPMC_ECC_CONFIG */
|
||||
#define ECCALGORITHM __BIT(16)
|
||||
#define ECCCS __BITS(3,1)
|
||||
#define ECC16B __BIT(7)
|
||||
#define ECCENABLE __BIT(0)
|
||||
/* GPMC_ECC_SIZE_CONFIG */
|
||||
#define ECCSIZE1 __BITS(29,22)
|
||||
|
||||
/* GPMC_CONFIG1_i */
|
||||
#define DEVICETYPE __BITS(11,10)
|
||||
#define DEVICESIZE __BITS(13,12)
|
||||
|
||||
#define MASKEDINT(mask, integer) ((integer) << (ffs(mask) - 1) & mask)
|
||||
|
||||
/* NAND status register */
|
||||
#define NAND_WP_BIT __BIT(4)
|
||||
|
||||
static int omap2_nand_match(device_t, cfdata_t, void *);
|
||||
static void omap2_nand_attach(device_t, device_t, void *);
|
||||
|
||||
static void omap2_nand_command(device_t self, uint8_t command);
|
||||
static void omap2_nand_address(device_t self, uint8_t address);
|
||||
static void omap2_nand_busy(device_t self);
|
||||
static void omap2_nand_read_1(device_t self, uint8_t *data);
|
||||
static void omap2_nand_write_1(device_t self, uint8_t data);
|
||||
static void omap2_nand_read_2(device_t self, uint16_t *data);
|
||||
static void omap2_nand_write_2(device_t self, uint16_t data);
|
||||
bool omap2_nand_isbusy(device_t self);
|
||||
static void omap2_nand_read_buf_1(device_t self, void *buf, size_t len);
|
||||
static void omap2_nand_read_buf_2(device_t self, void *buf, size_t len);
|
||||
static void omap2_nand_write_buf_1(device_t self, const void *buf, size_t len);
|
||||
static void omap2_nand_write_buf_2(device_t self, const void *buf, size_t len);
|
||||
|
||||
#ifdef OMAP2_NAND_HARDWARE_ECC
|
||||
static int omap2_nand_ecc_init(device_t self);
|
||||
static int omap2_nand_ecc_prepare(device_t self, int mode);
|
||||
static int omap2_nand_ecc_compute(device_t self, const uint8_t *data, uint8_t *ecc);
|
||||
static int omap2_nand_ecc_correct(device_t self, uint8_t *data, const uint8_t *oldecc,
|
||||
const uint8_t *calcecc);
|
||||
#endif
|
||||
|
||||
struct omap2_nand_softc {
|
||||
device_t sc_dev;
|
||||
device_t sc_nanddev;
|
||||
|
||||
int sc_cs;
|
||||
int sc_buswidth; /* 0: 8bit, 1: 16bit */
|
||||
|
||||
struct nand_interface sc_nand_if;
|
||||
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ioh;
|
||||
bus_space_handle_t sc_gpmc_ioh;
|
||||
|
||||
bus_size_t sc_cmd_reg;
|
||||
bus_size_t sc_addr_reg;
|
||||
bus_size_t sc_data_reg;
|
||||
};
|
||||
|
||||
static const char * compatible[] = {
|
||||
"ti,omap2-nand",
|
||||
"ti,omap2-onenand",
|
||||
NULL
|
||||
};
|
||||
|
||||
CFATTACH_DECL_NEW(omapnand, sizeof(struct omap2_nand_softc), omap2_nand_match,
|
||||
omap2_nand_attach, NULL, NULL);
|
||||
|
||||
static inline uint32_t
|
||||
gpmc_register_read(struct omap2_nand_softc *sc, bus_size_t reg)
|
||||
{
|
||||
return bus_space_read_4(sc->sc_iot, sc->sc_gpmc_ioh, reg);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gpmc_register_write(struct omap2_nand_softc *sc, bus_size_t reg, const uint32_t data)
|
||||
{
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_gpmc_ioh, reg, data);
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_command(device_t self, uint8_t command)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_cmd_reg, command);
|
||||
};
|
||||
|
||||
static void
|
||||
omap2_nand_address(device_t self, uint8_t address)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_addr_reg, address);
|
||||
};
|
||||
|
||||
bool
|
||||
omap2_nand_isbusy(device_t self)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
uint8_t status;
|
||||
|
||||
DELAY(1); /* just to be sure we are not early */
|
||||
|
||||
bus_space_write_1(sc->sc_iot, sc->sc_ioh,
|
||||
sc->sc_cmd_reg, ONFI_READ_STATUS);
|
||||
|
||||
DELAY(1);
|
||||
|
||||
status = bus_space_read_1(sc->sc_iot,
|
||||
sc->sc_ioh, sc->sc_data_reg);
|
||||
|
||||
return !(status & ONFI_STATUS_RDY);
|
||||
};
|
||||
|
||||
static int
|
||||
omap2_nand_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
struct flash_attach_args flash;
|
||||
bus_addr_t addr, part_addr;
|
||||
bus_size_t size, part_size;
|
||||
const u_int *prop;
|
||||
uint32_t val;
|
||||
int len, child;
|
||||
|
||||
if (fdtbus_get_reg(OF_parent(phandle), 0, &addr, &size) != 0) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_iot = faa->faa_bst;
|
||||
sc->sc_dev = self;
|
||||
|
||||
prop = fdtbus_get_prop(phandle, "reg", &len);
|
||||
if (prop == NULL || len < 4) {
|
||||
aprint_error(": couldn't read reg property\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_cs = be32toh(prop[0]);
|
||||
|
||||
/* map i/o space */
|
||||
if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_gpmc_ioh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
if (bus_space_subregion(sc->sc_iot, sc->sc_gpmc_ioh, GPMC_CS_CONFIG(sc->sc_cs), 0x30, &sc->sc_ioh) != 0) {
|
||||
aprint_error(": couldn't map cs registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": CS%d\n", sc->sc_cs);
|
||||
|
||||
sc->sc_cmd_reg = GPMC_NAND_COMMAND_0 - GPMC_CONFIG1_0;
|
||||
sc->sc_addr_reg = GPMC_NAND_ADDRESS_0 - GPMC_CONFIG1_0;
|
||||
sc->sc_data_reg = GPMC_NAND_DATA_0 - GPMC_CONFIG1_0;
|
||||
|
||||
/* turn off write protection if enabled */
|
||||
val = gpmc_register_read(sc, GPMC_CONFIG);
|
||||
val |= NAND_WP_BIT;
|
||||
gpmc_register_write(sc, GPMC_CONFIG, val);
|
||||
|
||||
/*
|
||||
* do the reset dance for NAND
|
||||
*/
|
||||
bus_space_write_1(sc->sc_iot, sc->sc_ioh,
|
||||
sc->sc_cmd_reg, ONFI_RESET);
|
||||
|
||||
omap2_nand_busy(self);
|
||||
|
||||
/* read GPMC_CONFIG1_i to get buswidth */
|
||||
val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPMC_CONFIG1_i);
|
||||
|
||||
if ((val & DEVICESIZE) == MASKEDINT(DEVICESIZE, 0x01)) {
|
||||
/* 16bit */
|
||||
sc->sc_buswidth = 1;
|
||||
} else if ((val & DEVICESIZE) == MASKEDINT(DEVICESIZE, 0x00)) {
|
||||
/* 8bit */
|
||||
sc->sc_buswidth = 0;
|
||||
} else {
|
||||
panic("invalid buswidth reported by config1");
|
||||
}
|
||||
|
||||
nand_init_interface(&sc->sc_nand_if);
|
||||
|
||||
sc->sc_nand_if.command = &omap2_nand_command;
|
||||
sc->sc_nand_if.address = &omap2_nand_address;
|
||||
sc->sc_nand_if.read_buf_1 = &omap2_nand_read_buf_1;
|
||||
sc->sc_nand_if.read_buf_2 = &omap2_nand_read_buf_2;
|
||||
sc->sc_nand_if.read_1 = &omap2_nand_read_1;
|
||||
sc->sc_nand_if.read_2 = &omap2_nand_read_2;
|
||||
sc->sc_nand_if.write_buf_1 = &omap2_nand_write_buf_1;
|
||||
sc->sc_nand_if.write_buf_2 = &omap2_nand_write_buf_2;
|
||||
sc->sc_nand_if.write_1 = &omap2_nand_write_1;
|
||||
sc->sc_nand_if.write_2 = &omap2_nand_write_2;
|
||||
sc->sc_nand_if.busy = &omap2_nand_busy;
|
||||
|
||||
#ifdef OMAP2_NAND_HARDWARE_ECC
|
||||
omap2_nand_ecc_init(self);
|
||||
sc->sc_nand_if.ecc_compute = &omap2_nand_ecc_compute;
|
||||
sc->sc_nand_if.ecc_correct = &omap2_nand_ecc_correct;
|
||||
sc->sc_nand_if.ecc_prepare = &omap2_nand_ecc_prepare;
|
||||
sc->sc_nand_if.ecc.necc_code_size = 3;
|
||||
sc->sc_nand_if.ecc.necc_block_size = 512;
|
||||
sc->sc_nand_if.ecc.necc_type = NAND_ECC_TYPE_HW;
|
||||
#else
|
||||
sc->sc_nand_if.ecc.necc_code_size = 3;
|
||||
sc->sc_nand_if.ecc.necc_block_size = 256;
|
||||
#endif /* OMAP2_NAND_HARDWARE_ECC */
|
||||
|
||||
if (!pmf_device_register1(sc->sc_dev, NULL, NULL, NULL))
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
"couldn't establish power handler\n");
|
||||
|
||||
sc->sc_nanddev = nand_attach_mi(&sc->sc_nand_if, sc->sc_dev);
|
||||
if (sc->sc_nanddev == NULL)
|
||||
return;
|
||||
|
||||
for (child = OF_child(phandle); child; child = OF_peer(child)) {
|
||||
if (!fdtbus_status_okay(child))
|
||||
continue;
|
||||
|
||||
if (fdtbus_get_reg(child, 0, &part_addr, &part_size) != 0) {
|
||||
aprint_error_dev(self, "couldn't parse partition %s\n",
|
||||
fdtbus_get_string(child, "name"));
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&flash, 0, sizeof(flash));
|
||||
flash.flash_if = &nand_flash_if;
|
||||
flash.partinfo.part_offset = part_addr;
|
||||
flash.partinfo.part_size = part_size;
|
||||
flash.partinfo.part_flags = 0;
|
||||
flash.partinfo.part_name = fdtbus_get_string(child, "label");
|
||||
if (flash.partinfo.part_name == NULL)
|
||||
flash.partinfo.part_name = fdtbus_get_string(child, "name");
|
||||
|
||||
config_found_ia(sc->sc_nanddev, "flashbus", &flash, flash_print);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_busy(device_t self)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
while (!(gpmc_register_read(sc, GPMC_STATUS) & WAIT0)) {
|
||||
DELAY(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_read_1(device_t self, uint8_t *data)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
*data = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->sc_data_reg);
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_write_1(device_t self, uint8_t data)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->sc_data_reg, data);
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_read_2(device_t self, uint16_t *data)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
*data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, sc->sc_data_reg);
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_write_2(device_t self, uint16_t data)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
bus_space_write_2(sc->sc_iot, sc->sc_ioh, sc->sc_data_reg, data);
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_read_buf_1(device_t self, void *buf, size_t len)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
KASSERT(buf != NULL);
|
||||
KASSERT(len >= 1);
|
||||
|
||||
bus_space_read_multi_1(sc->sc_iot, sc->sc_ioh,
|
||||
sc->sc_data_reg, buf, len);
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_read_buf_2(device_t self, void *buf, size_t len)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
KASSERT(buf != NULL);
|
||||
KASSERT(len >= 2);
|
||||
KASSERT(!(len & 0x01));
|
||||
|
||||
bus_space_read_multi_2(sc->sc_iot, sc->sc_ioh,
|
||||
sc->sc_data_reg, buf, len / 2);
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_write_buf_1(device_t self, const void *buf, size_t len)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
KASSERT(buf != NULL);
|
||||
KASSERT(len >= 1);
|
||||
|
||||
bus_space_write_multi_1(sc->sc_iot, sc->sc_ioh,
|
||||
sc->sc_data_reg, buf, len);
|
||||
}
|
||||
|
||||
static void
|
||||
omap2_nand_write_buf_2(device_t self, const void *buf, size_t len)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
|
||||
KASSERT(buf != NULL);
|
||||
KASSERT(len >= 2);
|
||||
KASSERT(!(len & 0x01));
|
||||
|
||||
bus_space_write_multi_2(sc->sc_iot, sc->sc_ioh,
|
||||
sc->sc_data_reg, buf, len / 2);
|
||||
}
|
||||
|
||||
#ifdef OMAP2_NAND_HARDWARE_ECC
|
||||
static uint32_t
|
||||
convert_ecc(const uint8_t *ecc)
|
||||
{
|
||||
return ecc[0] | (ecc[1] << 16) | ((ecc[2] & 0xf0) << 20) |
|
||||
((ecc[2] & 0x0f) << 8);
|
||||
}
|
||||
|
||||
static int
|
||||
omap2_nand_ecc_init(device_t self)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
uint32_t val;
|
||||
|
||||
val = gpmc_register_read(sc, GPMC_ECC_CONTROL);
|
||||
/* clear ecc, select ecc register 1 */
|
||||
val &= ~ECCPOINTER;
|
||||
val |= ECCCLEAR | MASKEDINT(ECCPOINTER, 1);
|
||||
gpmc_register_write(sc, GPMC_ECC_CONTROL, val);
|
||||
|
||||
/* XXX too many MAGIC */
|
||||
/* set ecc size to 512, set all regs to eccsize1*/
|
||||
val = gpmc_register_read(sc, GPMC_ECC_SIZE_CONFIG);
|
||||
val &= ~ECCSIZE1;
|
||||
val |= MASKEDINT(ECCSIZE1, 512) | 0x0f;
|
||||
gpmc_register_write(sc, GPMC_ECC_CONTROL, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
omap2_nand_ecc_compute(device_t self, const uint8_t *data, uint8_t *ecc)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
uint32_t val;
|
||||
|
||||
/* read ecc result register */
|
||||
val = gpmc_register_read(sc, GPMC_ECC1_RESULT);
|
||||
|
||||
ecc[0] = val & 0xff;
|
||||
ecc[1] = (val >> 16) & 0xff;
|
||||
ecc[2] = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
|
||||
|
||||
/* disable ecc engine */
|
||||
val = gpmc_register_read(sc, GPMC_ECC_CONFIG);
|
||||
val &= ~ECCENABLE;
|
||||
gpmc_register_write(sc, GPMC_ECC_CONFIG, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
omap2_nand_ecc_prepare(device_t self, int mode)
|
||||
{
|
||||
struct omap2_nand_softc *sc = device_private(self);
|
||||
uint32_t val;
|
||||
|
||||
/* same for read/write */
|
||||
switch (mode) {
|
||||
case NAND_ECC_READ:
|
||||
case NAND_ECC_WRITE:
|
||||
val = gpmc_register_read(sc, GPMC_ECC_CONTROL);
|
||||
/* clear ecc, select ecc register 1 */
|
||||
val &= ~ECCPOINTER;
|
||||
val |= ECCCLEAR | MASKEDINT(ECCPOINTER, 1);
|
||||
gpmc_register_write(sc, GPMC_ECC_CONTROL, val);
|
||||
|
||||
val = gpmc_register_read(sc, GPMC_ECC_CONFIG);
|
||||
val &= ~ECCCS;
|
||||
val |= ECCENABLE | MASKEDINT(ECCCS, sc->sc_cs);
|
||||
if (sc->sc_buswidth == 1)
|
||||
val |= ECC16B;
|
||||
else
|
||||
val &= ~ECC16B;
|
||||
gpmc_register_write(sc, GPMC_ECC_CONFIG, val);
|
||||
|
||||
break;
|
||||
default:
|
||||
aprint_error_dev(self, "invalid i/o mode for ecc prepare\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
omap2_nand_ecc_correct(device_t self, uint8_t *data, const uint8_t *oldecc,
|
||||
const uint8_t *calcecc)
|
||||
{
|
||||
uint32_t oecc, cecc, xor;
|
||||
uint16_t parity, offset;
|
||||
uint8_t bit;
|
||||
|
||||
oecc = convert_ecc(oldecc);
|
||||
cecc = convert_ecc(calcecc);
|
||||
|
||||
/* get the difference */
|
||||
xor = oecc ^ cecc;
|
||||
|
||||
/* the data was correct if all bits are zero */
|
||||
if (xor == 0x00)
|
||||
return NAND_ECC_OK;
|
||||
|
||||
switch (popcount32(xor)) {
|
||||
case 12:
|
||||
/* single byte error */
|
||||
parity = xor >> 16;
|
||||
bit = (parity & 0x07);
|
||||
offset = (parity >> 3) & 0x01ff;
|
||||
/* correct bit */
|
||||
data[offset] ^= (0x01 << bit);
|
||||
return NAND_ECC_CORRECTED;
|
||||
case 1:
|
||||
return NAND_ECC_INVALID;
|
||||
default:
|
||||
/* erased page! */
|
||||
if ((oecc == 0x0fff0fff) && (cecc == 0x00000000))
|
||||
return NAND_ECC_OK;
|
||||
|
||||
return NAND_ECC_TWOBIT;
|
||||
}
|
||||
}
|
||||
#endif /* !OMAP2_NAND_HARDWARE_ECC */
|
|
@ -0,0 +1,214 @@
|
|||
/* $NetBSD: omap3_cm.c,v 1.4.2.2 2019/11/27 13:46:44 martin 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(1, "$NetBSD: omap3_cm.c,v 1.4.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#define TI_PRCM_PRIVATE
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
#define CM_CORE1_BASE 0x0a00
|
||||
#define CM_CORE3_BASE 0x0a08
|
||||
#define CM_WKUP_BASE 0x0c00
|
||||
#define CM_PER_BASE 0x1000
|
||||
#define CM_USBHOST_BASE 0x1400
|
||||
|
||||
#define CM_FCLKEN 0x00
|
||||
#define CM_ICLKEN 0x10
|
||||
#define CM_AUTOIDLE 0x30
|
||||
#define CM_CLKSEL 0x40
|
||||
|
||||
static int omap3_cm_match(device_t, cfdata_t, void *);
|
||||
static void omap3_cm_attach(device_t, device_t, void *);
|
||||
|
||||
static int
|
||||
omap3_cm_hwmod_nopenable(struct ti_prcm_softc *sc, struct ti_prcm_clk *tc, int enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
omap3_cm_hwmod_enable(struct ti_prcm_softc *sc, struct ti_prcm_clk *tc, int enable)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = PRCM_READ(sc, tc->u.hwmod.reg + CM_FCLKEN);
|
||||
if (enable)
|
||||
val |= tc->u.hwmod.mask;
|
||||
else
|
||||
val &= ~tc->u.hwmod.mask;
|
||||
PRCM_WRITE(sc, tc->u.hwmod.reg + CM_FCLKEN, val);
|
||||
|
||||
val = PRCM_READ(sc, tc->u.hwmod.reg + CM_ICLKEN);
|
||||
if (enable)
|
||||
val |= tc->u.hwmod.mask;
|
||||
else
|
||||
val &= ~tc->u.hwmod.mask;
|
||||
PRCM_WRITE(sc, tc->u.hwmod.reg + CM_ICLKEN, val);
|
||||
|
||||
if (tc->u.hwmod.flags & TI_HWMOD_DISABLE_AUTOIDLE) {
|
||||
val = PRCM_READ(sc, tc->u.hwmod.reg + CM_AUTOIDLE);
|
||||
val &= ~tc->u.hwmod.mask;
|
||||
PRCM_WRITE(sc, tc->u.hwmod.reg + CM_AUTOIDLE, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OMAP3_CM_HWMOD_CORE1(_name, _bit, _parent, _flags) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_CORE1_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
|
||||
#define OMAP3_CM_HWMOD_CORE3(_name, _bit, _parent, _flags) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_CORE3_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
|
||||
#define OMAP3_CM_HWMOD_WKUP(_name, _bit, _parent, _flags) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_WKUP_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
|
||||
#define OMAP3_CM_HWMOD_PER(_name, _bit, _parent, _flags) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_PER_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
|
||||
#define OMAP3_CM_HWMOD_USBHOST(_name, _bit, _parent, _flags) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_USBHOST_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
|
||||
#define OMAP3_CM_HWMOD_NOP(_name, _parent) \
|
||||
TI_PRCM_HWMOD_MASK((_name), 0, 0, (_parent), omap3_cm_hwmod_nopenable, 0)
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,omap3-cm",
|
||||
NULL
|
||||
};
|
||||
|
||||
CFATTACH_DECL_NEW(omap3_cm, sizeof(struct ti_prcm_softc),
|
||||
omap3_cm_match, omap3_cm_attach, NULL, NULL);
|
||||
|
||||
static struct ti_prcm_clk omap3_cm_clks[] = {
|
||||
/* XXX until we get a proper clock tree */
|
||||
TI_PRCM_FIXED("FIXED_32K", 32768),
|
||||
TI_PRCM_FIXED("SYS_CLK", 13000000),
|
||||
TI_PRCM_FIXED("MMC_CLK", 96000000),
|
||||
TI_PRCM_FIXED_FACTOR("PERIPH_CLK", 1, 1, "SYS_CLK"),
|
||||
|
||||
OMAP3_CM_HWMOD_CORE1("usb_otg_hs", 4, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcbsp1", 9, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcbsp5", 10, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("timer10", 11, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("timer11", 12, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("uart1", 13, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("uart2", 14, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("i2c1", 15, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("i2c2", 16, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("i2c3", 17, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi1", 18, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi2", 19, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi3", 20, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi4", 21, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("hdq1w", 22, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mmc1", 24, "MMC_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mmc2", 25, "MMC_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mmc3", 30, "MMC_CLK", 0),
|
||||
|
||||
OMAP3_CM_HWMOD_CORE3("usb_tll_hs", 2, "PERIPH_CLK", TI_HWMOD_DISABLE_AUTOIDLE),
|
||||
|
||||
OMAP3_CM_HWMOD_WKUP("timer1", 0, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_WKUP("counter_32k", 2, "FIXED_32K", 0),
|
||||
OMAP3_CM_HWMOD_WKUP("gpio1", 3, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_WKUP("wd_timer2", 5, "FIXED_32K", 0),
|
||||
|
||||
OMAP3_CM_HWMOD_PER("mcbsp2", 0, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("mcbsp3", 1, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("mcbsp4", 2, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer2", 3, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer3", 4, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer4", 5, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer5", 6, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer6", 7, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer7", 8, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer8", 9, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer9", 10, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("uart3", 11, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("wd_timer3", 12, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("gpio2", 13, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("gpio3", 14, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("gpio4", 15, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("gpio5", 16, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("gpio6", 17, "PERIPH_CLK", 0),
|
||||
|
||||
OMAP3_CM_HWMOD_USBHOST("usb_host_hs", 0, "PERIPH_CLK", 0),
|
||||
|
||||
OMAP3_CM_HWMOD_NOP("gpmc", "PERIPH_CLK"),
|
||||
};
|
||||
|
||||
static void
|
||||
omap3_cm_initclocks(struct ti_prcm_softc *sc)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
/* Select SYS_CLK for GPTIMER 2 and 3 */
|
||||
val = PRCM_READ(sc, CM_PER_BASE + CM_CLKSEL);
|
||||
val |= __BIT(0); /* CLKSEL_GPT2 0x1: source is SYS_CLK */
|
||||
val |= __BIT(1); /* CLKSEL_GPT3 0x1: source is SYS_CLK */
|
||||
PRCM_WRITE(sc, CM_PER_BASE + CM_CLKSEL, val);
|
||||
}
|
||||
|
||||
static int
|
||||
omap3_cm_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
|
||||
omap3_cm_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_prcm_softc * const sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
int clocks;
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_phandle = faa->faa_phandle;
|
||||
sc->sc_bst = faa->faa_bst;
|
||||
|
||||
sc->sc_clks = omap3_cm_clks;
|
||||
sc->sc_nclks = __arraycount(omap3_cm_clks);
|
||||
|
||||
if (ti_prcm_attach(sc) != 0)
|
||||
return;
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": OMAP3xxx CM\n");
|
||||
|
||||
omap3_cm_initclocks(sc);
|
||||
|
||||
clocks = of_find_firstchild_byname(sc->sc_phandle, "clocks");
|
||||
if (clocks > 0)
|
||||
fdt_add_bus(self, clocks, faa);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,373 @@
|
|||
/* $NetBSD: omap3_dssreg.h,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 Michael Lorenz
|
||||
* 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: omap3_dssreg.h,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#ifndef OMAP3_DSSREG_H
|
||||
#define OMAP3_DSSREG_H
|
||||
|
||||
#define OMAPFB_DSS_REVISION 0x0000
|
||||
#define OMAPFB_DSS_SYSCONFIG 0x0010
|
||||
#define OMAPFB_DSS_SYSSTATUS 0x0014
|
||||
#define OMAPFB_DSS_IRQSTATUS 0x0018
|
||||
#define OMAPFB_DSS_CONTROL 0x0040
|
||||
#define OMAPFB_DSS_SDI_CONTROL 0x0044
|
||||
#define OMAPFB_DSS_PLL_CONTROL 0x0048
|
||||
#define OMAPFB_DSS_SDI_STATUS 0x005c
|
||||
|
||||
/* display controller */
|
||||
#define OMAPFB_DISPC_REVISION 0x0400
|
||||
#define OMAPFB_DISPC_SYSCONFIG 0x0410
|
||||
#define OMAPFB_DISPC_SYSSTATUS 0x0414
|
||||
#define OMAPFB_DISPC_IRQSTATUS 0x0418
|
||||
#define OMAPFB_DISPC_IRQENABLE 0x041c
|
||||
#define OMAPFB_DISPC_CONTROL 0x0440
|
||||
#define OMAPFB_DISPC_CONFIG 0x0444
|
||||
#define OMAPFB_DISPC_DEFAULT_COLOR_0 0x044c
|
||||
#define OMAPFB_DISPC_DEFAULT_COLOR_1 0x0450
|
||||
#define OMAPFB_DISPC_TRANS_COLOR_0 0x0454
|
||||
#define OMAPFB_DISPC_TRANS_COLOR_1 0x0458
|
||||
#define OMAPFB_DISPC_LINE_STATUS 0x045c
|
||||
#define OMAPFB_DISPC_LINE_NUMBER 0x0460
|
||||
#define OMAPFB_DISPC_TIMING_H 0x0464
|
||||
#define OMAPFB_DISPC_TIMING_V 0x0468
|
||||
#define OMAPFB_DISPC_POL_FREQ 0x046c
|
||||
#define OMAPFB_DISPC_DIVISOR 0x0470
|
||||
#define OMAPFB_DISPC_GLOBAL_ALPHA 0x0474
|
||||
#define OMAPFB_DISPC_SIZE_DIG 0x0478
|
||||
#define OMAPFB_DISPC_SIZE_LCD 0x047c
|
||||
#define OMAPFB_DISPC_GFX_BASE_0 0x0480
|
||||
#define OMAPFB_DISPC_GFX_BASE_1 0x0484
|
||||
#define OMAPFB_DISPC_GFX_POSITION 0x0488
|
||||
#define OMAPFB_DISPC_GFX_SIZE 0x048c
|
||||
#define OMAPFB_DISPC_GFX_ATTRIBUTES 0x04a0
|
||||
#define OMAPFB_DISPC_GFX_FIFO_THRESH 0x04a4
|
||||
#define OMAPFB_DISPC_GFX_FIFO_SZ_STATUS 0x04a8
|
||||
#define OMAPFB_DISPC_GFX_ROW_INC 0x04ac
|
||||
#define OMAPFB_DISPC_GFX_PIXEL_INC 0x04b0
|
||||
#define OMAPFB_DISPC_GFX_WINDOW_SKIP 0x04b4
|
||||
#define OMAPFB_DISPC_GFX_TABLE_BASE 0x04b8
|
||||
#define OMAPFB_DISPC_DATA_CYCLE_0 0x05d4
|
||||
#define OMAPFB_DISPC_DATA_CYCLE_1 0x05d8
|
||||
#define OMAPFB_DISPC_DATA_CYCLE_2 0x05dc
|
||||
#define OMAPFB_DISPC_CPR_COEFF_R 0x0620
|
||||
#define OMAPFB_DISPC_CPR_COEFF_G 0x0624
|
||||
#define OMAPFB_DISPC_CPR_COEFF_B 0x0628
|
||||
#define OMAPFB_DISPC_GFX_PRELOAD 0x062c
|
||||
|
||||
/* VID1 */
|
||||
#define OMAPFB_DISPC_VID1_BASE_0 0x04bc
|
||||
#define OMAPFB_DISPC_VID1_BASE_1 0x04c0
|
||||
#define OMAPFB_DISPC_VID1_POSITION 0x04c4
|
||||
#define OMAPFB_DISPC_VID1_SIZE 0x04c8 /* displayed size */
|
||||
#define OMAPFB_DISPC_VID1_ATTRIBUTES 0x04cc
|
||||
#define OMAPFB_DISPC_VID1_FIFO_THRESH 0x04d0
|
||||
#define OMAPFB_DISPC_VID1_FIFO_SZ_STAT 0x04d4
|
||||
#define OMAPFB_DISPC_VID1_ROW_INC 0x04d8
|
||||
#define OMAPFB_DISPC_VID1_PIXEL_INC 0x04dc
|
||||
#define OMAPFB_DISPC_VID1_FIR 0x04e0
|
||||
#define OMAPFB_DISPC_VID1_PICTURE_SIZE 0x04e4 /* original size */
|
||||
#define OMAPFB_DISPC_VID1_ACCU_0 0x04e8
|
||||
#define OMAPFB_DISPC_VID1_ACCU_1 0x04ec
|
||||
#define OMAPFB_DISPC_VID1_COEFF_H_0 0x04d0
|
||||
#define OMAPFB_DISPC_VID1_COEFF_HV_0 0x04d4
|
||||
#define OMAPFB_DISPC_VID1_COEFF_H_1 0x04d8
|
||||
#define OMAPFB_DISPC_VID1_COEFF_HV_1 0x04dc
|
||||
#define OMAPFB_DISPC_VID1_COEFF_H_2 0x04e0
|
||||
#define OMAPFB_DISPC_VID1_COEFF_HV_2 0x04e4
|
||||
#define OMAPFB_DISPC_VID1_COEFF_H_3 0x04e8
|
||||
#define OMAPFB_DISPC_VID1_COEFF_HV_3 0x04ec
|
||||
#define OMAPFB_DISPC_VID1_COEFF_H_4 0x04f0
|
||||
#define OMAPFB_DISPC_VID1_COEFF_HV_4 0x04f4
|
||||
#define OMAPFB_DISPC_VID1_COEFF_H_5 0x04f8
|
||||
#define OMAPFB_DISPC_VID1_COEFF_HV_5 0x04fc
|
||||
#define OMAPFB_DISPC_VID1_COEFF_H_6 0x0500
|
||||
#define OMAPFB_DISPC_VID1_COEFF_HV_6 0x0504
|
||||
#define OMAPFB_DISPC_VID1_COEFF_H_7 0x0508
|
||||
#define OMAPFB_DISPC_VID1_COEFF_HV_7 0x050c
|
||||
#define OMAPFB_DISPC_VID1_CONV_COEFF_0 0x0530
|
||||
#define OMAPFB_DISPC_VID1_CONV_COEFF_1 0x0534
|
||||
#define OMAPFB_DISPC_VID1_CONV_COEFF_2 0x0538
|
||||
#define OMAPFB_DISPC_VID1_CONV_COEFF_3 0x053c
|
||||
#define OMAPFB_DISPC_VID1_CONV_COEFF_4 0x0540
|
||||
#define OMAPFB_DISPC_VID1_FIR_COEFF_V0 0x05e0
|
||||
#define OMAPFB_DISPC_VID1_FIR_COEFF_V1 0x05e4
|
||||
#define OMAPFB_DISPC_VID1_FIR_COEFF_V2 0x05e8
|
||||
#define OMAPFB_DISPC_VID1_FIR_COEFF_V3 0x05ec
|
||||
#define OMAPFB_DISPC_VID1_FIR_COEFF_V4 0x05f0
|
||||
#define OMAPFB_DISPC_VID1_FIR_COEFF_V5 0x05f4
|
||||
#define OMAPFB_DISPC_VID1_FIR_COEFF_V6 0x05f8
|
||||
#define OMAPFB_DISPC_VID1_FIR_COEFF_V7 0x05fc
|
||||
#define OMAPFB_DISPC_VID1_PRELOAD 0x0630
|
||||
|
||||
/* VID2 */
|
||||
#define OMAPFB_DISPC_VID2_BASE_0 0x054c
|
||||
#define OMAPFB_DISPC_VID2_BASE_1 0x0550
|
||||
#define OMAPFB_DISPC_VID2_POSITION 0x0554
|
||||
#define OMAPFB_DISPC_VID2_SIZE 0x0558
|
||||
#define OMAPFB_DISPC_VID2_ATTRIBUTES 0x055c
|
||||
#define OMAPFB_DISPC_VID2_FIFO_THRESH 0x0560
|
||||
#define OMAPFB_DISPC_VID2_FIFO_SZ_STAT 0x0564
|
||||
#define OMAPFB_DISPC_VID2_ROW_INC 0x0568
|
||||
#define OMAPFB_DISPC_VID2_PIXEL_INC 0x056c
|
||||
#define OMAPFB_DISPC_VID2_FIR 0x0570
|
||||
#define OMAPFB_DISPC_VID2_PICTURE_SIZE 0x0574
|
||||
#define OMAPFB_DISPC_VID2_ACCU_0 0x0578
|
||||
#define OMAPFB_DISPC_VID2_ACCU_1 0x057c
|
||||
#define OMAPFB_DISPC_VID2_COEFF_H_0 0x0580
|
||||
#define OMAPFB_DISPC_VID2_COEFF_HV_0 0x0584
|
||||
#define OMAPFB_DISPC_VID2_COEFF_H_1 0x0588
|
||||
#define OMAPFB_DISPC_VID2_COEFF_HV_1 0x058c
|
||||
#define OMAPFB_DISPC_VID2_COEFF_H_2 0x0590
|
||||
#define OMAPFB_DISPC_VID2_COEFF_HV_2 0x0594
|
||||
#define OMAPFB_DISPC_VID2_COEFF_H_3 0x0598
|
||||
#define OMAPFB_DISPC_VID2_COEFF_HV_3 0x059c
|
||||
#define OMAPFB_DISPC_VID2_COEFF_H_4 0x05a0
|
||||
#define OMAPFB_DISPC_VID2_COEFF_HV_4 0x05a4
|
||||
#define OMAPFB_DISPC_VID2_COEFF_H_5 0x05a8
|
||||
#define OMAPFB_DISPC_VID2_COEFF_HV_5 0x05ac
|
||||
#define OMAPFB_DISPC_VID2_COEFF_H_6 0x05b0
|
||||
#define OMAPFB_DISPC_VID2_COEFF_HV_6 0x05b4
|
||||
#define OMAPFB_DISPC_VID2_COEFF_H_7 0x05b8
|
||||
#define OMAPFB_DISPC_VID2_COEFF_HV_7 0x05bc
|
||||
#define OMAPFB_DISPC_VID2_CONV_COEFF_0 0x05c0
|
||||
#define OMAPFB_DISPC_VID2_CONV_COEFF_1 0x05c4
|
||||
#define OMAPFB_DISPC_VID2_CONV_COEFF_2 0x05c8
|
||||
#define OMAPFB_DISPC_VID2_CONV_COEFF_3 0x05cc
|
||||
#define OMAPFB_DISPC_VID2_CONV_COEFF_4 0x05d0
|
||||
#define OMAPFB_DISPC_VID2_FIR_COEFF_V0 0x0670
|
||||
#define OMAPFB_DISPC_VID2_FIR_COEFF_V1 0x0674
|
||||
#define OMAPFB_DISPC_VID2_FIR_COEFF_V2 0x0678
|
||||
#define OMAPFB_DISPC_VID2_FIR_COEFF_V3 0x067c
|
||||
#define OMAPFB_DISPC_VID2_FIR_COEFF_V4 0x0680
|
||||
#define OMAPFB_DISPC_VID2_FIR_COEFF_V5 0x0684
|
||||
#define OMAPFB_DISPC_VID2_FIR_COEFF_V6 0x0688
|
||||
#define OMAPFB_DISPC_VID2_FIR_COEFF_V7 0x068c
|
||||
#define OMAPFB_DISPC_VID2_PRELOAD 0x0634
|
||||
|
||||
/* video encoder */
|
||||
#define OMAPFB_VENC_REV_ID 0x0c00
|
||||
#define OMAPFB_VENC_STATUS 0x0c04
|
||||
#define OMAPFB_VENC_F_CONTROL 0x0c08
|
||||
#define OMAPFB_VENC_VIDOUT_CTRL 0x0c10
|
||||
#define OMAPFB_VENC_SYNC_CTRL 0x0c14
|
||||
#define OMAPFB_VENC_LLEN 0x0c1c
|
||||
#define OMAPFB_VENC_FLENS 0x0c20
|
||||
#define OMAPFB_VENC_HFLTR_CTRL 0x0c24
|
||||
#define OMAPFB_VENC_CC_CARR_WSS_CARR 0x0c28
|
||||
#define OMAPFB_VENC_C_PHASE 0x0c2c
|
||||
#define OMAPFB_VENC_GAIN_U 0x0c30
|
||||
#define OMAPFB_VENC_GAIN_V 0x0c34
|
||||
#define OMAPFB_VENC_GAIN_Y 0x0c38
|
||||
#define OMAPFB_VENC_BLACK_LEVEL 0x0c3c
|
||||
#define OMAPFB_VENC_BLANK_LEVEL 0x0c40
|
||||
#define OMAPFB_VENC_X_COLOR 0x0c44
|
||||
#define OMAPFB_VENC_M_CONTROL 0x0c48
|
||||
#define OMAPFB_VENC_BSTAMP_WSS_DATA 0x0c4c
|
||||
#define OMAPFB_VENC_S_CARR 0x0c50
|
||||
#define OMAPFB_VENC_LINE21 0x0c54
|
||||
#define OMAPFB_VENC_LN_SEL 0x0c58
|
||||
#define OMAPFB_VENC_L21_WC_CTL 0x0c5c
|
||||
#define OMAPFB_VENC_HTRIGGER_VTRIGGER 0x0c60
|
||||
#define OMAPFB_VENC_SAVID_EAVID 0x0c64
|
||||
#define OMAPFB_VENC_FLEN_FAL 0x0c68
|
||||
#define OMAPFB_VENC_LAL_PHASE_RESET 0x0c6c
|
||||
#define OMAPFB_VENC_HS_INT_START_STOP_X 0x0c70
|
||||
#define OMAPFB_VENC_HS_EXT_START_STOP_X 0x0c74
|
||||
#define OMAPFB_VENC_VS_INT_START 0x0c78
|
||||
#define OMAPFB_VENC_VS_INT_STOP_X_VS_INT_START_Y 0x0c7c
|
||||
#define OMAPFB_VENC_VS_INT_STOP_Y_VS_EXT_START_X 0x0c80
|
||||
#define OMAPFB_VENC_VS_EXT_STOP_X_VS_EXT_START_Y 0x0c84
|
||||
#define OMAPFB_VENC_VS_EXT_STOP_Y 0x0c88
|
||||
#define OMAPFB_VENC_AVID_START_STOP_X 0x0c90
|
||||
#define OMAPFB_VENC_AVID_START_STOP_Y 0x0c94
|
||||
#define OMAPFB_VENC_FID_START_X_FID_START_Y 0x0ca0
|
||||
#define OMAPFB_VENC_FID_INT_OFFSET_Y_FID_EXT_START_X 0x0ca4
|
||||
#define OMAPFB_VENC_FID_EXT_START_Y_FID_EXT_OFFSET_Y 0x0ca8
|
||||
#define OMAPFB_VENC_TVDETGP_INT_START_STOP_X 0x0cb0
|
||||
#define OMAPFB_VENC_TVDETGP_INT_START_STOP_Y 0x0cb4
|
||||
#define OMAPFB_VENC_GEN_CTRL 0x0cb8
|
||||
#define OMAPFB_VENC_OUTPUT_CONTROL 0x0cc4
|
||||
#define OMAPFB_VENC_OUTPUT_TEST 0x0cc8
|
||||
|
||||
/* revision registers */
|
||||
#define OMAP_REVISION_MINOR_MASK 0x0000000f
|
||||
#define OMAP_REVISION_MAJOR_MASK 0x000000f0
|
||||
|
||||
/* sysconfig registers */
|
||||
#define OMAP_SYSCONF_AUTOIDLE 0x00000001
|
||||
#define OMAP_SYSCONF_SOFTRESET 0x00000002
|
||||
|
||||
/* sysstatus registers */
|
||||
#define OMAP_SYSSTAT_RESET_DONE 0x00000001
|
||||
|
||||
/* OMAPFB_DSS_IRQSTATUS */
|
||||
#define OMAP_DSSIRQ_DISPC 0x00000001
|
||||
#define OMAP_DSSIRQ_DSI 0x00000002
|
||||
|
||||
/* OMAPFB_DSS_CONTROL */
|
||||
#define OMAP_DSSCTRL_VENC_SVIDEO 0x00000040 /* composite otherwise */
|
||||
#define OMAP_DSSCTRL_POWERDN_BGZ 0x00000020 /* power-down band gap up */
|
||||
#define OMAP_DSSCTRL_DAC_DEMEN 0x00000010 /* dynamic element match */
|
||||
#define OMAP_DSSCTRL_VENC_CLOCK_4X 0x00000008
|
||||
#define OMAP_DSSCTRL_CLOCK_MODE 0x00000004
|
||||
#define OMAP_DSSCTRL_DSI_CLK_SWITCH 0x00000002 /* use DSI PLL */
|
||||
#define OMAP_DSSCTRL_DISPC_CLK_SWITCH 0x00000001 /* use DSI PLL */
|
||||
|
||||
/* additional bits in OMAPFB_DISPC_SYSCONFIG */
|
||||
#define OMAP_DISPC_SYSC_FORCE_STANDBY 0x00000000
|
||||
#define OMAP_DISPC_SYSC_NO_STANDBY 0x00001000
|
||||
#define OMAP_DISPC_SYSC_SMART_STANDBY 0x00002000
|
||||
#define OMAP_DISPC_SYSC_STANDBY_MASK 0x00003000
|
||||
#define OMAP_DISPC_SYSC_CLOCKS_OFF 0x00000000
|
||||
#define OMAP_DISPC_SYSC_FCLOCK_OFF 0x00000100
|
||||
#define OMAP_DISPC_SYSC_ICLOCK_OFF 0x00000200
|
||||
#define OMAP_DISPC_SYSC_CLOCK_ON 0x00000300
|
||||
#define OMAP_DISPC_SYSC_CLOCK_MASK 0x00000300
|
||||
#define OMAP_DISPC_SYSC_FORCE_IDLE 0x00000000
|
||||
#define OMAP_DISPC_SYSC_NO_IDLE 0x00000008
|
||||
#define OMAP_DISPC_SYSC_SMART_IDLE 0x00000010
|
||||
#define OMAP_DISPC_SYSC_IDLE_MASK 0x00000018
|
||||
#define OMAP_DISPC_SYSC_WAKEUP_ENABLE 0x00000004
|
||||
|
||||
/* OMAPFB_DISPC_GFX_ATTRIBUTES */
|
||||
#define OMAP_DISPC_ATTR_REFRESH_FIFO 0x00008000 /* refresh from FIFO only */
|
||||
#define OMAP_DISPC_ATTR_PRIORITY_HIGH 0x00004000
|
||||
#define OMAP_DISPC_ATTR_ROT_NONE 0x00000000
|
||||
#define OMAP_DISPC_ATTR_ROT_90 0x00001000 /* for 24bit packed only */
|
||||
#define OMAP_DISPC_ATTR_ROT_180 0x00002000
|
||||
#define OMAP_DISPC_ATTR_ROT_270 0x00003000
|
||||
#define OMAP_DISPC_ATTR_FIFO_PRELOAD 0x00000800 /* use threshold for FIFO */
|
||||
#define OMAP_DISPC_ATTR_BIG_ENDIAN 0x00000400 /* little endian otherwise */
|
||||
#define OMAP_DISPC_ATTR_NIBBLE 0x00000200 /* for < 8 bit only */
|
||||
#define OMAP_DISPC_ATTR_24BIT_OUT 0x00000100 /* LCD otherwise */
|
||||
#define OMAP_DISPC_ATTR_BURST_4x32 0x00000000
|
||||
#define OMAP_DISPC_ATTR_BURST_8x32 0x00000040
|
||||
#define OMAP_DISPC_ATTR_BURST_16x32 0x00000080
|
||||
#define OMAP_DISPC_ATTR_REPLICATION 0x00000020
|
||||
#define OMAP_DISPC_ATTR_8BIT 0x00000006
|
||||
#define OMAP_DISPC_ATTR_RGB12 0x00000008
|
||||
#define OMAP_DISPC_ATTR_ARGB16 0x0000000a
|
||||
#define OMAP_DISPC_ATTR_RGB16 0x0000000c
|
||||
#define OMAP_DISPC_ATTR_RGB24 0x00000010 /* 32bit pixels */
|
||||
#define OMAP_DISPC_ATTR_RGB24P 0x00000012 /* 24bit packed */
|
||||
#define OMAP_DISPC_ATTR_ARGB32 0x00000018
|
||||
#define OMAP_DISPC_ATTR_RGBA32 0x0000001a
|
||||
#define OMAP_DISPC_ATTR_RGBX 0x0000001c
|
||||
#define OMAP_DISPC_ATTR_ENABLE 0x00000001
|
||||
|
||||
/* OMAPFB_DISPC_CONTROL */
|
||||
#define OMAP_DISPC_CTRL_LCD_ACTIVE_HIGH 0x20000000
|
||||
#define OMAP_DISPC_CTRL_LCD_SIGNAL 0x10000000
|
||||
#define OMAP_DISPC_CTRL_PIXEL_CLOCK 0x08000000
|
||||
#define OMAP_DISPC_CTRL_GO_DIGITAL 0x00000040
|
||||
#define OMAP_DISPC_CTRL_GO_LCD 0x00000020
|
||||
#define OMAP_DISPC_CTRL_MONO_8_BYTE 0x00000010 /* 4 otherwise */
|
||||
#define OMAP_DISPC_CTRL_ACTIVE_MTRX 0x00000008 /* disable STN dither */
|
||||
#define OMAP_DISPC_CTRL_MONO 0x00000004
|
||||
#define OMAP_DISPC_CTRL_DIGITAL_ENABLE 0x00000002
|
||||
#define OMAP_DISPC_CTRL_LCD_ENABLE 0x00000001
|
||||
|
||||
/* OMAPFB_VENC_F_CONTROL */
|
||||
#define OMAP_VENCFCTL_RESET 0x00000100
|
||||
#define OMAP_VENCFCTL_VID_EXTERNAL 0x00000000
|
||||
#define OMAP_VENCFCTL_VID_COLOR_BAR 0x00000040
|
||||
#define OMAP_VENCFCTL_VID_BACKGROUND 0x00000080
|
||||
#define OMAP_VENCFCTL_RGBF 0x00000020
|
||||
#define OMAP_VENCFCTL_BG_COLOR_MASK 0x0000001c
|
||||
#define OMAP_VENCFCTL_FMT_444RGB 0x00000000
|
||||
#define OMAP_VENCFCTL_FMT_444 0x00000001
|
||||
#define OMAP_VENCFCTL_FMT_422 0x00000002
|
||||
#define OMAP_VENCFCTL_FMT_ITU_422 0x00000003
|
||||
|
||||
/* OMAPFB_DISPC_CONFIG */
|
||||
#define OMAP_DISPC_CFG_TV_ALPHA_EN 0x00080000
|
||||
#define OMAP_DISPC_CFG_LCD_ALPHA_EN 0x00040000
|
||||
#define OMAP_DISPC_CFG_FIFO_FILL_ALL 0x00020000 /* fill all FIFOs if at least one is low */
|
||||
#define OMAP_DISPC_CFG_FIFOHANDCHECK 0x00010000
|
||||
#define OMAP_DISPC_CFG_CPR 0x00008000 /* color phase rotation */
|
||||
#define OMAP_DISPC_CFG_FIFOMERGE 0x00004000
|
||||
#define OMAP_DISPC_CFG_TCKDIGSELECTION 0x00002000 /* transp. color key */
|
||||
#define OMAP_DISPC_CFG_TCKDIGENABLE 0x00001000
|
||||
#define OMAP_DISPC_CFG_TCKLCDSELECTION 0x00000800 /* transp. color key */
|
||||
#define OMAP_DISPC_CFG_TCKLCDENABLE 0x00000400
|
||||
#define OMAP_DISPC_CFG_FUNCGATED 0x00000200 /* functional clocks */
|
||||
#define OMAP_DISPC_CFG_ACBIAS_GATED 0x00000100
|
||||
#define OMAP_DISPC_CFG_VSYNC_GATED 0x00000080
|
||||
#define OMAP_DISPC_CFG_HSYNC_GATED 0x00000040
|
||||
#define OMAP_DISPC_CFG_PIXELCLK_GATED 0x00000020
|
||||
#define OMAP_DISPC_CFG_PIXELDATA_GATED 0x00000010
|
||||
#define OMAP_DISPC_CFG_PALGAMMATABLE 0x00000008 /* use LUT as gamma in >8bit */
|
||||
#define OMAP_DISPC_CFG_LUT_LOAD_ALWAYS 0x00000000
|
||||
#define OMAP_DISPC_CFG_LUT_LOAD 0x00000002
|
||||
#define OMAP_DISPC_CFG_LUT_LOAD_F_ONLY 0x00000004 /* only frame data */
|
||||
#define OMAP_DISPC_CFG_LUT_LOAD_ONCE 0x00000006 /* load once, then 4 */
|
||||
#define OMAP_DISPC_CFG_PIXEL_GATED 0x00000001 /* active matrix only */
|
||||
|
||||
/* OMAPFB_DISPC_VIDn_ATTRIBUTES */
|
||||
#define OMAP_VID_ATTR_SELFREFRESH 0x01000000 /* no DMA, display from FIFO only */
|
||||
#define OMAP_VID_ATTR_HIGH_PRIORITY 0x00800000
|
||||
#define OMAP_VID_ATTR_BUFFER_SPLIT 0x00400000
|
||||
#define OMAP_VID_ATTR_TAP_5 0x00200000 /* resize, 3 taps otherwise */
|
||||
#define OMAP_VID_ATTR_DMA_OPT 0x00100000 /* for rotation */
|
||||
#define OMAP_VID_ATTR_FIFO_PRELOAD 0x00080000 /* use high threshold reg */
|
||||
#define OMAP_VID_ATTR_ROWREPEAT 0x00040000 /* for YUV */
|
||||
#define OMAP_VID_ATTR_BIG_ENDIAN 0x00020000
|
||||
#define OMAP_VID_ATTR_CHANNEL_24BIT 0x00010000 /* LCD otherwise */
|
||||
#define OMAP_VID_ATTR_BURST_4x32 0x00000000
|
||||
#define OMAP_VID_ATTR_BURST_8x32 0x00004000
|
||||
#define OMAP_VID_ATTR_BURST_16x32 0x00008000
|
||||
#define OMAP_VID_ATTR_BURST_MASK 0x0000c000
|
||||
#define OMAP_VID_ATTR_ROT_NONE 0x00000000
|
||||
#define OMAP_VID_ATTR_ROT_90 0x00001000
|
||||
#define OMAP_VID_ATTR_ROT_180 0x00002000
|
||||
#define OMAP_VID_ATTR_ROT_270 0x00003000
|
||||
#define OMAP_VID_ATTR_ROT_MASK 0x00003000
|
||||
#define OMAP_VID_ATTR_FULLRANGE 0x00000800 /* YUV */
|
||||
#define OMAP_VID_ATTR_REPLICATION 0x00000400 /* 16bit -> 24bit */
|
||||
#define OMAP_VID_ATTR_COLORSPACE_CONV 0x00000200 /* CbYCr -> RGB */
|
||||
#define OMAP_VID_ATTR_VRESIZE_UP 0x00000100 /* down otherwise */
|
||||
#define OMAP_VID_ATTR_HRESIZE_UP 0x00000080
|
||||
#define OMAP_VID_ATTR_VRESIZE_ENABLE 0x00000040
|
||||
#define OMAP_VID_ATTR_HRESIZE_ENABLE 0x00000020
|
||||
/* VID1 doesn't support any alpha formats */
|
||||
#define OMAP_VID_ATTR_RGB12 0x00000008
|
||||
#define OMAP_VID_ATTR_ARGB16 0x0000000a
|
||||
#define OMAP_VID_ATTR_RGB16 0x0000000c
|
||||
#define OMAP_VID_ATTR_RGB24 0x00000010 /* 32bit pixels */
|
||||
#define OMAP_VID_ATTR_RGB24P 0x00000012 /* 24bit packed */
|
||||
#define OMAP_VID_ATTR_YUV2 0x00000014
|
||||
#define OMAP_VID_ATTR_UYVY 0x00000016
|
||||
#define OMAP_VID_ATTR_ARGB32 0x00000018
|
||||
#define OMAP_VID_ATTR_RGBA32 0x0000001a
|
||||
#define OMAP_VID_ATTR_RGBX 0x0000001c
|
||||
|
||||
#define OMAP_VID_ATTR_ENABLE 0x00000001
|
||||
|
||||
#endif /* OMAP3_DSSREG_H */
|
|
@ -0,0 +1,200 @@
|
|||
/* $NetBSD: omap3_platform.c,v 1.2.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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_console.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: omap3_platform.c,v 1.2.2.2 2019/11/27 13:46:44 martin 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 <dev/ic/ns16550reg.h>
|
||||
#include <dev/ic/comreg.h>
|
||||
|
||||
#include <evbarm/fdt/platform.h>
|
||||
#include <evbarm/fdt/machdep.h>
|
||||
|
||||
#include <net/if_ether.h>
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
#define OMAP3_L4_CORE_VBASE KERNEL_IO_VBASE
|
||||
#define OMAP3_L4_CORE_PBASE 0x48000000
|
||||
#define OMAP3_L4_CORE_SIZE 0x00100000
|
||||
|
||||
#define OMAP3_L4_WKUP_VBASE (OMAP3_L4_CORE_VBASE + OMAP3_L4_CORE_SIZE)
|
||||
#define OMAP3_L4_WKUP_PBASE 0x48300000
|
||||
#define OMAP3_L4_WKUP_SIZE 0x00100000
|
||||
|
||||
#define OMAP3_L4_PER_VBASE (OMAP3_L4_WKUP_VBASE + OMAP3_L4_WKUP_SIZE)
|
||||
#define OMAP3_L4_PER_PBASE 0x49000000
|
||||
#define OMAP3_L4_PER_SIZE 0x00100000
|
||||
|
||||
#define OMAP3_PRCM_BASE 0x48306000
|
||||
#define OMAP3_PRCM_GR_BASE (OMAP3_PRCM_BASE + 0x1200)
|
||||
#define PRM_RSTCTRL (OMAP3_PRCM_GR_BASE + 0x50)
|
||||
#define PRM_RSTCTRL_RST_DPLL3 __BIT(2)
|
||||
|
||||
#define OMAP3_32KTIMER_BASE 0x48320000
|
||||
#define REG_32KSYNCNT_CR (OMAP3_32KTIMER_BASE + 0x10)
|
||||
|
||||
static inline vaddr_t
|
||||
omap3_phystovirt(paddr_t pa)
|
||||
{
|
||||
if (pa >= OMAP3_L4_CORE_PBASE &&
|
||||
pa < OMAP3_L4_CORE_PBASE + OMAP3_L4_CORE_SIZE)
|
||||
return (pa - OMAP3_L4_CORE_PBASE) + OMAP3_L4_CORE_VBASE;
|
||||
|
||||
if (pa >= OMAP3_L4_WKUP_PBASE &&
|
||||
pa < OMAP3_L4_WKUP_PBASE + OMAP3_L4_WKUP_SIZE)
|
||||
return (pa - OMAP3_L4_WKUP_PBASE) + OMAP3_L4_WKUP_VBASE;
|
||||
|
||||
if (pa >= OMAP3_L4_PER_PBASE &&
|
||||
pa < OMAP3_L4_PER_PBASE + OMAP3_L4_PER_SIZE)
|
||||
return (pa - OMAP3_L4_PER_PBASE) + OMAP3_L4_PER_VBASE;
|
||||
|
||||
panic("%s: pa %#x not in devmap", __func__, (uint32_t)pa);
|
||||
}
|
||||
|
||||
#define OMAP3_PHYSTOVIRT(pa) \
|
||||
(((pa) - OMAP3_L4_CORE_VBASE) + OMAP3_L4_CORE_PBASE)
|
||||
|
||||
extern struct arm32_bus_dma_tag arm_generic_dma_tag;
|
||||
extern struct bus_space arm_generic_bs_tag;
|
||||
extern struct bus_space arm_generic_a4x_bs_tag;
|
||||
|
||||
static const struct pmap_devmap *
|
||||
omap3_platform_devmap(void)
|
||||
{
|
||||
static const struct pmap_devmap devmap[] = {
|
||||
DEVMAP_ENTRY(OMAP3_L4_CORE_VBASE,
|
||||
OMAP3_L4_CORE_PBASE,
|
||||
OMAP3_L4_CORE_SIZE),
|
||||
DEVMAP_ENTRY(OMAP3_L4_WKUP_VBASE,
|
||||
OMAP3_L4_WKUP_PBASE,
|
||||
OMAP3_L4_WKUP_SIZE),
|
||||
DEVMAP_ENTRY(OMAP3_L4_PER_VBASE,
|
||||
OMAP3_L4_PER_PBASE,
|
||||
OMAP3_L4_PER_SIZE),
|
||||
DEVMAP_ENTRY_END
|
||||
};
|
||||
|
||||
return devmap;
|
||||
}
|
||||
|
||||
static void
|
||||
omap3_platform_init_attach_args(struct fdt_attach_args *faa)
|
||||
{
|
||||
faa->faa_bst = &arm_generic_bs_tag;
|
||||
faa->faa_a4x_bst = &arm_generic_a4x_bs_tag;
|
||||
faa->faa_dmat = &arm_generic_dma_tag;
|
||||
}
|
||||
|
||||
void omap3_platform_early_putchar(char);
|
||||
|
||||
void
|
||||
omap3_platform_early_putchar(char c)
|
||||
{
|
||||
#ifdef CONSADDR
|
||||
volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
|
||||
(volatile uint32_t *)omap3_phystovirt(CONSADDR):
|
||||
(volatile uint32_t *)CONSADDR;
|
||||
|
||||
while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
|
||||
;
|
||||
|
||||
uartaddr[com_data] = htole32(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
omap3_platform_device_register(device_t self, void *aux)
|
||||
{
|
||||
}
|
||||
|
||||
static u_int
|
||||
omap3_platform_uart_freq(void)
|
||||
{
|
||||
return 48000000U;
|
||||
}
|
||||
|
||||
static void
|
||||
omap3_platform_reset(void)
|
||||
{
|
||||
volatile uint32_t *rstctrl =
|
||||
(volatile uint32_t *)omap3_phystovirt(PRM_RSTCTRL);
|
||||
|
||||
*rstctrl |= PRM_RSTCTRL_RST_DPLL3;
|
||||
|
||||
for (;;)
|
||||
__asm("wfi");
|
||||
}
|
||||
|
||||
static void
|
||||
omap3_platform_delay(u_int n)
|
||||
{
|
||||
volatile uint32_t *cr =
|
||||
(volatile uint32_t *)omap3_phystovirt(REG_32KSYNCNT_CR);
|
||||
uint32_t cur, prev;
|
||||
|
||||
long ticks = howmany(n * 32768, 1000000);
|
||||
prev = *cr;
|
||||
while (ticks > 0) {
|
||||
cur = *cr;
|
||||
if (cur >= prev)
|
||||
ticks -= (cur - prev);
|
||||
else
|
||||
ticks -= (UINT32_MAX - cur + prev);
|
||||
prev = cur;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct arm_platform omap3_platform = {
|
||||
.ap_devmap = omap3_platform_devmap,
|
||||
.ap_bootstrap = arm_fdt_cpu_bootstrap,
|
||||
.ap_init_attach_args = omap3_platform_init_attach_args,
|
||||
.ap_device_register = omap3_platform_device_register,
|
||||
.ap_reset = omap3_platform_reset,
|
||||
.ap_delay = omap3_platform_delay,
|
||||
.ap_uart_freq = omap3_platform_uart_freq,
|
||||
};
|
||||
|
||||
ARM_PLATFORM(omap3, "ti,omap3", &omap3_platform);
|
|
@ -0,0 +1,77 @@
|
|||
/* $NetBSD: omap3_prm.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: omap3_prm.c,v 1.1.2.2 2019/11/27 13:46:44 martin 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/kmem.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
static int omap3_prm_match(device_t, cfdata_t, void *);
|
||||
static void omap3_prm_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(omap3_prm, 0, omap3_prm_match, omap3_prm_attach, NULL, NULL);
|
||||
|
||||
static const char * compatible[] = {
|
||||
"ti,omap3-prm",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int
|
||||
omap3_prm_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
|
||||
omap3_prm_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
int clocks;
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal("\n");
|
||||
|
||||
fdt_add_bus(self, phandle, faa);
|
||||
|
||||
clocks = of_find_firstchild_byname(phandle, "clocks");
|
||||
if (clocks > 0)
|
||||
fdt_add_bus(self, clocks, faa);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ti_com.c,v 1.4 2018/12/08 17:46:10 thorpej Exp $ */
|
||||
/* $NetBSD: ti_com.c,v 1.4.4.1 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
|
||||
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__KERNEL_RCSID(1, "$NetBSD: ti_com.c,v 1.4 2018/12/08 17:46:10 thorpej Exp $");
|
||||
__KERNEL_RCSID(1, "$NetBSD: ti_com.c,v 1.4.4.1 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -79,7 +79,6 @@ ti_com_attach(device_t parent, device_t self, void *aux)
|
|||
bus_space_handle_t bsh;
|
||||
bus_space_tag_t bst;
|
||||
char intrstr[128];
|
||||
struct clk *hwmod;
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
int error;
|
||||
|
@ -106,9 +105,7 @@ ti_com_attach(device_t parent, device_t self, void *aux)
|
|||
return;
|
||||
}
|
||||
|
||||
hwmod = ti_prcm_get_hwmod(phandle, 0);
|
||||
KASSERT(hwmod != NULL);
|
||||
if (clk_enable(hwmod) != 0) {
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
/* $NetBSD: ti_cpufreq.c,v 1.2.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: ti_cpufreq.c,v 1.2.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
#include <dev/fdt/syscon.h>
|
||||
|
||||
static bool ti_opp_probed = false;
|
||||
static bool (*ti_opp_supportedfn)(const int, const int);
|
||||
static struct syscon *ti_opp_syscon;
|
||||
|
||||
#ifdef SOC_AM33XX
|
||||
|
||||
#define AM33XX_REV_OFFSET 0x0600
|
||||
#define AM33XX_REV_MASK 0xf0000000
|
||||
#define AM33XX_EFUSE_OFFSET 0x07fc
|
||||
#define AM33XX_EFUSE_MASK 0x00001fff
|
||||
#define AM33XX_EFUSE_DEFAULT 0x1e2f
|
||||
|
||||
static const char * const am33xx_compatible[] = { "ti,am33xx", NULL };
|
||||
|
||||
static bool
|
||||
am33xx_opp_supported(const int opp_table, const int opp_node)
|
||||
{
|
||||
const u_int *supported_hw;
|
||||
uint32_t efuse, rev;
|
||||
int len;
|
||||
|
||||
syscon_lock(ti_opp_syscon);
|
||||
rev = __SHIFTOUT(syscon_read_4(ti_opp_syscon, AM33XX_REV_OFFSET), AM33XX_REV_MASK);
|
||||
efuse = __SHIFTOUT(syscon_read_4(ti_opp_syscon, AM33XX_EFUSE_OFFSET), AM33XX_EFUSE_MASK);
|
||||
syscon_unlock(ti_opp_syscon);
|
||||
|
||||
if (efuse == 0)
|
||||
efuse = AM33XX_EFUSE_DEFAULT;
|
||||
efuse = ~efuse;
|
||||
|
||||
supported_hw = fdtbus_get_prop(opp_node, "opp-supported-hw", &len);
|
||||
if (len != 8)
|
||||
return false;
|
||||
|
||||
if ((rev & be32toh(supported_hw[0])) == 0)
|
||||
return false;
|
||||
|
||||
if ((efuse & be32toh(supported_hw[1])) == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ti_opp_probe(const int opp_table)
|
||||
{
|
||||
if (ti_opp_probed)
|
||||
return;
|
||||
ti_opp_probed = true;
|
||||
|
||||
ti_opp_syscon = fdtbus_syscon_acquire(opp_table, "syscon");
|
||||
|
||||
#ifdef SOC_AM33XX
|
||||
if (ti_opp_syscon && of_match_compatible(OF_finddevice("/"), am33xx_compatible))
|
||||
ti_opp_supportedfn = am33xx_opp_supported;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
ti_opp_supported(const int opp_table, const int opp_node)
|
||||
{
|
||||
ti_opp_probe(opp_table);
|
||||
|
||||
if (!of_hasprop(opp_node, "opp-supported-hw"))
|
||||
return true;
|
||||
|
||||
return ti_opp_supportedfn ? ti_opp_supportedfn(opp_table, opp_node) : false;
|
||||
}
|
||||
|
||||
FDT_OPP(ti, "operating-points-v2-ti-cpu", ti_opp_supported);
|
|
@ -0,0 +1,202 @@
|
|||
/* $NetBSD: ti_div_clock.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: ti_div_clock.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/clk/clk_backend.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,divider-clock",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int ti_div_clock_match(device_t, cfdata_t, void *);
|
||||
static void ti_div_clock_attach(device_t, device_t, void *);
|
||||
|
||||
static struct clk *ti_div_clock_decode(device_t, int, const void *, size_t);
|
||||
|
||||
static const struct fdtbus_clock_controller_func ti_div_clock_fdt_funcs = {
|
||||
.decode = ti_div_clock_decode
|
||||
};
|
||||
|
||||
static struct clk *ti_div_clock_get(void *, const char *);
|
||||
static void ti_div_clock_put(void *, struct clk *);
|
||||
static u_int ti_div_clock_get_rate(void *, struct clk *);
|
||||
static struct clk *ti_div_clock_get_parent(void *, struct clk *);
|
||||
|
||||
static const struct clk_funcs ti_div_clock_clk_funcs = {
|
||||
.get = ti_div_clock_get,
|
||||
.put = ti_div_clock_put,
|
||||
.get_rate = ti_div_clock_get_rate,
|
||||
.get_parent = ti_div_clock_get_parent,
|
||||
};
|
||||
|
||||
struct ti_div_clock_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 clk sc_clk;
|
||||
};
|
||||
|
||||
#define RD4(sc) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, 0)
|
||||
#define WR4(sc, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, 0, (val))
|
||||
|
||||
CFATTACH_DECL_NEW(ti_div_clock, sizeof(struct ti_div_clock_softc),
|
||||
ti_div_clock_match, ti_div_clock_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
ti_div_clock_match(device_t parent, cfdata_t cf, void *aux)
|
||||
{
|
||||
const struct fdt_attach_args *faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_div_clock_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_div_clock_softc * const sc = device_private(self);
|
||||
const struct fdt_attach_args *faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
bus_addr_t addr, base_addr;
|
||||
|
||||
const int prcm_phandle = OF_parent(OF_parent(phandle));
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, NULL) != 0 ||
|
||||
fdtbus_get_reg(prcm_phandle, 0, &base_addr, NULL) != 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, base_addr + addr, 4, 0, &sc->sc_bsh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_clkdom.name = device_xname(self);
|
||||
sc->sc_clkdom.funcs = &ti_div_clock_clk_funcs;
|
||||
sc->sc_clkdom.priv = sc;
|
||||
|
||||
sc->sc_clk.domain = &sc->sc_clkdom;
|
||||
sc->sc_clk.name = kmem_asprintf("%s", faa->faa_name);
|
||||
clk_attach(&sc->sc_clk);
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": TI divider clock (%s)\n", sc->sc_clk.name);
|
||||
|
||||
fdtbus_register_clock_controller(self, phandle, &ti_div_clock_fdt_funcs);
|
||||
}
|
||||
|
||||
static struct clk *
|
||||
ti_div_clock_decode(device_t dev, int cc_phandle, const void *data,
|
||||
size_t len)
|
||||
{
|
||||
struct ti_div_clock_softc * const sc = device_private(dev);
|
||||
|
||||
return &sc->sc_clk;
|
||||
}
|
||||
|
||||
static struct clk *
|
||||
ti_div_clock_get(void *priv, const char *name)
|
||||
{
|
||||
struct ti_div_clock_softc * const sc = priv;
|
||||
|
||||
return &sc->sc_clk;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_div_clock_put(void *priv, struct clk *clk)
|
||||
{
|
||||
}
|
||||
|
||||
static u_int
|
||||
ti_div_clock_get_rate(void *priv, struct clk *clk)
|
||||
{
|
||||
struct ti_div_clock_softc * const sc = priv;
|
||||
struct clk *clk_parent = clk_get_parent(clk);
|
||||
uint64_t parent_rate;
|
||||
uint32_t val, max_val, mask;
|
||||
u_int div, max_div, bit_shift;
|
||||
|
||||
if (clk_parent == NULL)
|
||||
return 0;
|
||||
|
||||
if (of_hasprop(sc->sc_phandle, "ti,index-power-of-two"))
|
||||
return EINVAL; /* not supported yet */
|
||||
|
||||
const int start_index = of_hasprop(sc->sc_phandle, "ti,index-starts-at-one") ? 1 : 0;
|
||||
|
||||
if (of_getprop_uint32(sc->sc_phandle, "ti,bit-shift", &bit_shift) != 0)
|
||||
bit_shift = 0;
|
||||
|
||||
if (of_getprop_uint32(sc->sc_phandle, "ti,max-div", &max_div) == 0) {
|
||||
max_val = start_index + max_div;
|
||||
while (!powerof2(max_val))
|
||||
max_val++;
|
||||
mask = (max_val - 1) << bit_shift;
|
||||
} else {
|
||||
/*
|
||||
* The bindings allow for this, but it is not yet supported
|
||||
* by this driver.
|
||||
*/
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
val = RD4(sc);
|
||||
div = __SHIFTOUT(val, mask) + (start_index ? 0 : 1);
|
||||
if (div == 0)
|
||||
return EINVAL;
|
||||
|
||||
parent_rate = clk_get_rate(clk_parent);
|
||||
|
||||
return (u_int)(parent_rate / div);
|
||||
}
|
||||
|
||||
static struct clk *
|
||||
ti_div_clock_get_parent(void *priv, struct clk *clk)
|
||||
{
|
||||
struct ti_div_clock_softc * const sc = priv;
|
||||
|
||||
return fdtbus_clock_get_index(sc->sc_phandle, 0);
|
||||
}
|
|
@ -0,0 +1,345 @@
|
|||
/* $NetBSD: ti_dpll_clock.c,v 1.2.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: ti_dpll_clock.c,v 1.2.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/clk/clk_backend.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#define DPLL_MULT __BITS(18,8)
|
||||
#define DPLL_DIV __BITS(6,0)
|
||||
|
||||
#define AM3_ST_MN_BYPASS __BIT(8)
|
||||
#define AM3_ST_DPLL_CLK __BIT(0)
|
||||
|
||||
#define AM3_DPLL_EN __BITS(2,0)
|
||||
#define AM3_DPLL_EN_NM_BYPASS 4
|
||||
#define AM3_DPLL_EN_LOCK 7
|
||||
|
||||
#define OMAP3_ST_MPU_CLK __BIT(0)
|
||||
|
||||
#define OMAP3_EN_MPU_DPLL __BITS(2,0)
|
||||
#define OMAP3_EN_MPU_DPLL_BYPASS 5
|
||||
#define OMAP3_EN_MPU_DPLL_LOCK 7
|
||||
|
||||
#define OMAP3_CORE_DPLL_CLKOUT_DIV __BITS(31,27)
|
||||
#define OMAP3_CORE_DPLL_MULT __BITS(26,16)
|
||||
#define OMAP3_CORE_DPLL_DIV __BITS(14,8)
|
||||
|
||||
static int ti_dpll_clock_match(device_t, cfdata_t, void *);
|
||||
static void ti_dpll_clock_attach(device_t, device_t, void *);
|
||||
|
||||
static struct clk *ti_dpll_clock_decode(device_t, int, const void *, size_t);
|
||||
|
||||
static const struct fdtbus_clock_controller_func ti_dpll_clock_fdt_funcs = {
|
||||
.decode = ti_dpll_clock_decode
|
||||
};
|
||||
|
||||
static struct clk *ti_dpll_clock_get(void *, const char *);
|
||||
static void ti_dpll_clock_put(void *, struct clk *);
|
||||
static u_int ti_dpll_clock_get_rate(void *, struct clk *);
|
||||
static struct clk *ti_dpll_clock_get_parent(void *, struct clk *);
|
||||
|
||||
static int am3_dpll_clock_set_rate(void *, struct clk *, u_int);
|
||||
|
||||
static const struct clk_funcs am3_dpll_clock_clk_funcs = {
|
||||
.get = ti_dpll_clock_get,
|
||||
.put = ti_dpll_clock_put,
|
||||
.set_rate = am3_dpll_clock_set_rate,
|
||||
.get_rate = ti_dpll_clock_get_rate,
|
||||
.get_parent = ti_dpll_clock_get_parent,
|
||||
};
|
||||
|
||||
static int omap3_dpll_clock_set_rate(void *, struct clk *, u_int);
|
||||
|
||||
static const struct clk_funcs omap3_dpll_clock_clk_funcs = {
|
||||
.get = ti_dpll_clock_get,
|
||||
.put = ti_dpll_clock_put,
|
||||
.set_rate = omap3_dpll_clock_set_rate,
|
||||
.get_rate = ti_dpll_clock_get_rate,
|
||||
.get_parent = ti_dpll_clock_get_parent,
|
||||
};
|
||||
|
||||
static u_int omap3_dpll_core_clock_get_rate(void *, struct clk *);
|
||||
|
||||
static const struct clk_funcs omap3_dpll_core_clock_clk_funcs = {
|
||||
.get = ti_dpll_clock_get,
|
||||
.put = ti_dpll_clock_put,
|
||||
.get_rate = omap3_dpll_core_clock_get_rate,
|
||||
.get_parent = ti_dpll_clock_get_parent,
|
||||
};
|
||||
|
||||
static const struct of_compat_data compat_data[] = {
|
||||
{ "ti,am3-dpll-clock", (uintptr_t)&am3_dpll_clock_clk_funcs },
|
||||
{ "ti,omap3-dpll-clock", (uintptr_t)&omap3_dpll_clock_clk_funcs },
|
||||
{ "ti,omap3-dpll-core-clock", (uintptr_t)&omap3_dpll_core_clock_clk_funcs },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
enum {
|
||||
REG_CONTROL,
|
||||
REG_IDLEST,
|
||||
REG_MULT_DIV1,
|
||||
NREG
|
||||
};
|
||||
|
||||
struct ti_dpll_clock_softc {
|
||||
device_t sc_dev;
|
||||
int sc_phandle;
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh[NREG];
|
||||
|
||||
struct clk_domain sc_clkdom;
|
||||
struct clk sc_clk;
|
||||
};
|
||||
|
||||
#define RD4(sc, space) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh[(space)], 0)
|
||||
#define WR4(sc, space, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh[(space)], 0, (val))
|
||||
|
||||
CFATTACH_DECL_NEW(ti_dpll_clock, sizeof(struct ti_dpll_clock_softc),
|
||||
ti_dpll_clock_match, ti_dpll_clock_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
ti_dpll_clock_match(device_t parent, cfdata_t cf, void *aux)
|
||||
{
|
||||
const struct fdt_attach_args *faa = aux;
|
||||
|
||||
return of_match_compat_data(faa->faa_phandle, compat_data);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_dpll_clock_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_dpll_clock_softc * const sc = device_private(self);
|
||||
const struct fdt_attach_args *faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
const struct clk_funcs *clkfuncs;
|
||||
bus_addr_t addr[NREG], base_addr;
|
||||
u_int n;
|
||||
|
||||
const int prcm_phandle = OF_parent(OF_parent(phandle));
|
||||
if (fdtbus_get_reg(prcm_phandle, 0, &base_addr, NULL) != 0) {
|
||||
aprint_error(": couldn't get prcm registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; n < NREG; n++) {
|
||||
if (fdtbus_get_reg(phandle, n, &addr[n], NULL) != 0) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_phandle = phandle;
|
||||
sc->sc_bst = faa->faa_bst;
|
||||
for (n = 0; n < NREG; n++) {
|
||||
if (bus_space_map(sc->sc_bst, base_addr + addr[n], 4, 0, &sc->sc_bsh[n]) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
clkfuncs = (const void *)of_search_compatible(phandle, compat_data)->data;
|
||||
|
||||
sc->sc_clkdom.name = device_xname(self);
|
||||
sc->sc_clkdom.funcs = clkfuncs;
|
||||
sc->sc_clkdom.priv = sc;
|
||||
|
||||
sc->sc_clk.domain = &sc->sc_clkdom;
|
||||
sc->sc_clk.name = kmem_asprintf("%s", faa->faa_name);
|
||||
clk_attach(&sc->sc_clk);
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": TI DPLL clock (%s)\n", sc->sc_clk.name);
|
||||
|
||||
fdtbus_register_clock_controller(self, phandle, &ti_dpll_clock_fdt_funcs);
|
||||
}
|
||||
|
||||
static struct clk *
|
||||
ti_dpll_clock_decode(device_t dev, int cc_phandle, const void *data,
|
||||
size_t len)
|
||||
{
|
||||
struct ti_dpll_clock_softc * const sc = device_private(dev);
|
||||
|
||||
return &sc->sc_clk;
|
||||
}
|
||||
|
||||
static struct clk *
|
||||
ti_dpll_clock_get(void *priv, const char *name)
|
||||
{
|
||||
struct ti_dpll_clock_softc * const sc = priv;
|
||||
|
||||
return &sc->sc_clk;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_dpll_clock_put(void *priv, struct clk *clk)
|
||||
{
|
||||
}
|
||||
|
||||
static u_int
|
||||
ti_dpll_clock_get_rate(void *priv, struct clk *clk)
|
||||
{
|
||||
struct ti_dpll_clock_softc * const sc = priv;
|
||||
struct clk *clk_parent = clk_get_parent(clk);
|
||||
uint32_t val;
|
||||
uint64_t parent_rate;
|
||||
|
||||
if (clk_parent == NULL)
|
||||
return 0;
|
||||
|
||||
val = RD4(sc, REG_MULT_DIV1);
|
||||
const u_int mult = __SHIFTOUT(val, DPLL_MULT);
|
||||
const u_int div = __SHIFTOUT(val, DPLL_DIV) + 1;
|
||||
|
||||
parent_rate = clk_get_rate(clk_parent);
|
||||
|
||||
return (u_int)((mult * parent_rate) / div);
|
||||
}
|
||||
|
||||
static struct clk *
|
||||
ti_dpll_clock_get_parent(void *priv, struct clk *clk)
|
||||
{
|
||||
struct ti_dpll_clock_softc * const sc = priv;
|
||||
|
||||
/* XXX assume ref clk */
|
||||
return fdtbus_clock_get_index(sc->sc_phandle, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
am3_dpll_clock_set_rate(void *priv, struct clk *clk, u_int rate)
|
||||
{
|
||||
struct ti_dpll_clock_softc * const sc = priv;
|
||||
struct clk *clk_parent = clk_get_parent(clk);
|
||||
uint64_t parent_rate;
|
||||
uint32_t control, mult_div1;
|
||||
|
||||
if (clk_parent == NULL)
|
||||
return ENXIO;
|
||||
|
||||
parent_rate = clk_get_rate(clk_parent);
|
||||
if (parent_rate == 0)
|
||||
return EIO;
|
||||
|
||||
const u_int div = (parent_rate / 1000000) - 1;
|
||||
const u_int mult = rate / (parent_rate / (div + 1));
|
||||
if (mult < 2 || mult > 2047)
|
||||
return EINVAL;
|
||||
|
||||
control = RD4(sc, REG_CONTROL);
|
||||
control &= ~AM3_DPLL_EN;
|
||||
control |= __SHIFTIN(AM3_DPLL_EN_NM_BYPASS, AM3_DPLL_EN);
|
||||
WR4(sc, REG_CONTROL, control);
|
||||
|
||||
while ((RD4(sc, REG_IDLEST) & AM3_ST_MN_BYPASS) != 0)
|
||||
;
|
||||
|
||||
mult_div1 = __SHIFTIN(mult, DPLL_MULT);
|
||||
mult_div1 |= __SHIFTIN(div, DPLL_DIV);
|
||||
WR4(sc, REG_MULT_DIV1, mult_div1);
|
||||
|
||||
control &= ~AM3_DPLL_EN;
|
||||
control |= __SHIFTIN(AM3_DPLL_EN_LOCK, AM3_DPLL_EN);
|
||||
WR4(sc, REG_CONTROL, control);
|
||||
|
||||
while ((RD4(sc, REG_IDLEST) & AM3_ST_DPLL_CLK) != 0)
|
||||
;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
omap3_dpll_clock_set_rate(void *priv, struct clk *clk, u_int rate)
|
||||
{
|
||||
struct ti_dpll_clock_softc * const sc = priv;
|
||||
struct clk *clk_parent = clk_get_parent(clk);
|
||||
uint64_t parent_rate;
|
||||
uint32_t control, mult_div1;
|
||||
|
||||
if (clk_parent == NULL)
|
||||
return ENXIO;
|
||||
|
||||
parent_rate = clk_get_rate(clk_parent);
|
||||
|
||||
const u_int div = (parent_rate / 1000000) - 1;
|
||||
const u_int mult = rate / (parent_rate / (div + 1));
|
||||
if (mult < 2 || mult > 2047)
|
||||
return EINVAL;
|
||||
|
||||
control = RD4(sc, REG_CONTROL);
|
||||
control &= ~OMAP3_EN_MPU_DPLL;
|
||||
control |= __SHIFTIN(OMAP3_EN_MPU_DPLL_BYPASS, OMAP3_EN_MPU_DPLL);
|
||||
WR4(sc, REG_CONTROL, control);
|
||||
|
||||
delay(10);
|
||||
|
||||
mult_div1 = __SHIFTIN(mult, DPLL_MULT);
|
||||
mult_div1 |= __SHIFTIN(div, DPLL_DIV);
|
||||
WR4(sc, REG_MULT_DIV1, mult_div1);
|
||||
|
||||
control &= ~OMAP3_EN_MPU_DPLL;
|
||||
control |= __SHIFTIN(OMAP3_EN_MPU_DPLL_LOCK, OMAP3_EN_MPU_DPLL);
|
||||
WR4(sc, REG_CONTROL, control);
|
||||
|
||||
while ((RD4(sc, REG_IDLEST) & OMAP3_ST_MPU_CLK) != 0)
|
||||
;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u_int
|
||||
omap3_dpll_core_clock_get_rate(void *priv, struct clk *clk)
|
||||
{
|
||||
struct ti_dpll_clock_softc * const sc = priv;
|
||||
struct clk *clk_parent = clk_get_parent(clk);
|
||||
uint32_t val;
|
||||
uint64_t parent_rate;
|
||||
|
||||
if (clk_parent == NULL)
|
||||
return 0;
|
||||
|
||||
val = RD4(sc, REG_MULT_DIV1);
|
||||
const u_int mult = __SHIFTOUT(val, OMAP3_CORE_DPLL_MULT);
|
||||
const u_int div = __SHIFTOUT(val, OMAP3_CORE_DPLL_DIV) + 1;
|
||||
const u_int postdiv = __SHIFTOUT(val, OMAP3_CORE_DPLL_CLKOUT_DIV);
|
||||
|
||||
parent_rate = clk_get_rate(clk_parent);
|
||||
|
||||
return (u_int)((mult * parent_rate) / div) / postdiv;
|
||||
}
|
|
@ -0,0 +1,550 @@
|
|||
/* $NetBSD: ti_edma.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2014 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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: ti_edma.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/intr.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/bitops.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
#include <arm/ti/ti_edma.h>
|
||||
|
||||
#define NUM_DMA_CHANNELS 64
|
||||
#define NUM_PARAM_SETS 256
|
||||
#define MAX_PARAM_PER_CHANNEL 32
|
||||
|
||||
#ifdef EDMA_DEBUG
|
||||
int edmadebug = 1;
|
||||
#define DPRINTF(n,s) do { if ((n) <= edmadebug) device_printf s; } while (0)
|
||||
#else
|
||||
#define DPRINTF(n,s) do {} while (0)
|
||||
#endif
|
||||
|
||||
struct edma_softc;
|
||||
|
||||
struct edma_channel {
|
||||
struct edma_softc *ch_sc;
|
||||
enum edma_type ch_type;
|
||||
uint8_t ch_index;
|
||||
void (*ch_callback)(void *);
|
||||
void *ch_callbackarg;
|
||||
unsigned int ch_nparams;
|
||||
};
|
||||
|
||||
struct edma_softc {
|
||||
device_t sc_dev;
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ioh;
|
||||
kmutex_t sc_lock;
|
||||
struct edma_channel sc_dma[NUM_DMA_CHANNELS];
|
||||
|
||||
void *sc_ih;
|
||||
|
||||
uint32_t sc_dmamask[NUM_DMA_CHANNELS / 32];
|
||||
uint32_t sc_parammask[NUM_PARAM_SETS / 32];
|
||||
};
|
||||
|
||||
static int edma_match(device_t, cfdata_t, void *);
|
||||
static void edma_attach(device_t, device_t, void *);
|
||||
|
||||
static void edma_init(struct edma_softc *);
|
||||
static int edma_intr(void *);
|
||||
static void edma_write_param(struct edma_softc *,
|
||||
unsigned int, const struct edma_param *);
|
||||
static bool edma_bit_isset(uint32_t *, unsigned int);
|
||||
static void edma_bit_set(uint32_t *, unsigned int);
|
||||
static void edma_bit_clr(uint32_t *, unsigned int);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_edma, sizeof(struct edma_softc),
|
||||
edma_match, edma_attach, NULL, NULL);
|
||||
|
||||
#define EDMA_READ(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))
|
||||
#define EDMA_WRITE(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
|
||||
|
||||
static const char * compatible[] = {
|
||||
"ti,edma3-tpcc",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int
|
||||
edma_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
edma_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct edma_softc *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;
|
||||
int idx;
|
||||
|
||||
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(": failed to decode interrupt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_iot = faa->faa_bst;
|
||||
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": EDMA Channel Controller\n");
|
||||
|
||||
for (idx = 0; idx < NUM_DMA_CHANNELS; idx++) {
|
||||
struct edma_channel *ch = &sc->sc_dma[idx];
|
||||
ch->ch_sc = sc;
|
||||
ch->ch_type = EDMA_TYPE_DMA;
|
||||
ch->ch_index = idx;
|
||||
ch->ch_callback = NULL;
|
||||
ch->ch_callbackarg = NULL;
|
||||
ch->ch_nparams = 0;
|
||||
}
|
||||
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error_dev(self, "couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
||||
edma_init(sc);
|
||||
|
||||
sc->sc_ih = fdtbus_intr_establish_byname(phandle, "edma3_ccint",
|
||||
IPL_VM, FDT_INTR_MPSAFE, edma_intr, sc);
|
||||
if (sc->sc_ih == NULL) {
|
||||
aprint_error_dev(self, "failed to establish interrupt\n");
|
||||
return;
|
||||
}
|
||||
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hardware initialization
|
||||
*/
|
||||
static void
|
||||
edma_init(struct edma_softc *sc)
|
||||
{
|
||||
struct edma_param param;
|
||||
uint32_t val;
|
||||
int idx;
|
||||
|
||||
val = EDMA_READ(sc, EDMA_CCCFG_REG);
|
||||
if (val & EDMA_CCCFG_CHMAP_EXIST) {
|
||||
for (idx = 0; idx < NUM_DMA_CHANNELS; idx++) {
|
||||
EDMA_WRITE(sc, EDMA_DCHMAP_REG(idx),
|
||||
__SHIFTIN(0, EDMA_DCHMAP_PAENTRY));
|
||||
}
|
||||
}
|
||||
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.ep_bcnt = 1;
|
||||
for (idx = 0; idx < NUM_PARAM_SETS; idx++) {
|
||||
edma_write_param(sc, idx, ¶m);
|
||||
}
|
||||
|
||||
/* reserve PaRAM entry 0 for dummy slot */
|
||||
edma_bit_set(sc->sc_parammask, 0);
|
||||
for (idx = 1; idx <= 32; idx++) {
|
||||
edma_bit_set(sc->sc_parammask, idx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a PaRAM entry
|
||||
*/
|
||||
static void
|
||||
edma_write_param(struct edma_softc *sc,
|
||||
unsigned int idx, const struct edma_param *ep)
|
||||
{
|
||||
EDMA_WRITE(sc, EDMA_PARAM_OPT_REG(idx), ep->ep_opt);
|
||||
EDMA_WRITE(sc, EDMA_PARAM_SRC_REG(idx), ep->ep_src);
|
||||
EDMA_WRITE(sc, EDMA_PARAM_CNT_REG(idx),
|
||||
__SHIFTIN(ep->ep_bcnt, EDMA_PARAM_CNT_BCNT) |
|
||||
__SHIFTIN(ep->ep_acnt, EDMA_PARAM_CNT_ACNT));
|
||||
EDMA_WRITE(sc, EDMA_PARAM_DST_REG(idx), ep->ep_dst);
|
||||
EDMA_WRITE(sc, EDMA_PARAM_BIDX_REG(idx),
|
||||
__SHIFTIN(ep->ep_dstbidx, EDMA_PARAM_BIDX_DSTBIDX) |
|
||||
__SHIFTIN(ep->ep_srcbidx, EDMA_PARAM_BIDX_SRCBIDX));
|
||||
EDMA_WRITE(sc, EDMA_PARAM_LNK_REG(idx),
|
||||
__SHIFTIN(ep->ep_bcntrld, EDMA_PARAM_LNK_BCNTRLD) |
|
||||
__SHIFTIN(ep->ep_link, EDMA_PARAM_LNK_LINK));
|
||||
EDMA_WRITE(sc, EDMA_PARAM_CIDX_REG(idx),
|
||||
__SHIFTIN(ep->ep_dstcidx, EDMA_PARAM_CIDX_DSTCIDX) |
|
||||
__SHIFTIN(ep->ep_srccidx, EDMA_PARAM_CIDX_SRCCIDX));
|
||||
EDMA_WRITE(sc, EDMA_PARAM_CCNT_REG(idx),
|
||||
__SHIFTIN(ep->ep_ccnt, EDMA_PARAM_CCNT_CCNT));
|
||||
}
|
||||
|
||||
static bool
|
||||
edma_bit_isset(uint32_t *bits, unsigned int bit)
|
||||
{
|
||||
return !!(bits[bit >> 5] & (1 << (bit & 0x1f)));
|
||||
}
|
||||
|
||||
static void
|
||||
edma_bit_set(uint32_t *bits, unsigned int bit)
|
||||
{
|
||||
bits[bit >> 5] |= (1 << (bit & 0x1f));
|
||||
}
|
||||
|
||||
static void
|
||||
edma_bit_clr(uint32_t *bits, unsigned int bit)
|
||||
{
|
||||
bits[bit >> 5] &= ~(1 << (bit & 0x1f));
|
||||
}
|
||||
|
||||
static int
|
||||
edma_intr(void *priv)
|
||||
{
|
||||
struct edma_softc *sc = priv;
|
||||
uint64_t ipr, ier;
|
||||
int bit, idx;
|
||||
|
||||
ipr = EDMA_READ(sc, EDMA_IPR_REG);
|
||||
ipr |= (uint64_t)EDMA_READ(sc, EDMA_IPRH_REG) << 32;
|
||||
if (ipr == 0)
|
||||
return 0;
|
||||
|
||||
ier = EDMA_READ(sc, EDMA_IER_REG);
|
||||
ier |= (uint64_t)EDMA_READ(sc, EDMA_IERH_REG) << 32;
|
||||
|
||||
DPRINTF(2, (sc->sc_dev, "ipr = 0x%016llx ier 0x%016llx\n", ipr, ier));
|
||||
|
||||
EDMA_WRITE(sc, EDMA_ICR_REG, ipr & 0xffffffff);
|
||||
EDMA_WRITE(sc, EDMA_ICRH_REG, ipr >> 32);
|
||||
|
||||
while ((bit = ffs64(ipr)) != 0) {
|
||||
idx = bit - 1;
|
||||
ipr &= ~__BIT(idx);
|
||||
if (!(ier & __BIT(idx)))
|
||||
continue;
|
||||
if (!edma_bit_isset(sc->sc_dmamask, idx))
|
||||
continue;
|
||||
|
||||
sc->sc_dma[idx].ch_callback(sc->sc_dma[idx].ch_callbackarg);
|
||||
}
|
||||
|
||||
EDMA_WRITE(sc, EDMA_IEVAL_REG, EDMA_IEVAL_EVAL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a DMA channel. Currently only DMA types are supported, not QDMA.
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
struct edma_channel *
|
||||
edma_channel_alloc(enum edma_type type, unsigned int drq,
|
||||
void (*cb)(void *), void *cbarg)
|
||||
{
|
||||
struct edma_softc *sc;
|
||||
device_t dev;
|
||||
struct edma_channel *ch = NULL;
|
||||
|
||||
KASSERT(drq < __arraycount(sc->sc_dma));
|
||||
KASSERT(type == EDMA_TYPE_DMA); /* QDMA not implemented */
|
||||
KASSERT(cb != NULL);
|
||||
KASSERT(cbarg != NULL);
|
||||
|
||||
dev = device_find_by_driver_unit("tiedma", 0);
|
||||
if (dev == NULL)
|
||||
return NULL;
|
||||
sc = device_private(dev);
|
||||
|
||||
mutex_enter(&sc->sc_lock);
|
||||
if (!edma_bit_isset(sc->sc_dmamask, drq)) {
|
||||
ch = &sc->sc_dma[drq];
|
||||
KASSERT(ch->ch_callback == NULL);
|
||||
KASSERT(ch->ch_index == drq);
|
||||
ch->ch_callback = cb;
|
||||
ch->ch_callbackarg = cbarg;
|
||||
edma_bit_set(sc->sc_dmamask, drq);
|
||||
}
|
||||
|
||||
if (ch == NULL)
|
||||
goto done;
|
||||
|
||||
EDMA_WRITE(sc, EDMA_DRAE_REG(0), sc->sc_dmamask[0]);
|
||||
EDMA_WRITE(sc, EDMA_DRAEH_REG(0), sc->sc_dmamask[1]);
|
||||
|
||||
if (ch->ch_index < 32) {
|
||||
EDMA_WRITE(sc, EDMA_ICR_REG, __BIT(ch->ch_index));
|
||||
EDMA_WRITE(sc, EDMA_IESR_REG, __BIT(ch->ch_index));
|
||||
} else {
|
||||
EDMA_WRITE(sc, EDMA_ICRH_REG, __BIT(ch->ch_index - 32));
|
||||
EDMA_WRITE(sc, EDMA_IESRH_REG, __BIT(ch->ch_index - 32));
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_exit(&sc->sc_lock);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free a DMA channel allocated with edma_channel_alloc
|
||||
*/
|
||||
void
|
||||
edma_channel_free(struct edma_channel *ch)
|
||||
{
|
||||
struct edma_softc *sc = ch->ch_sc;
|
||||
|
||||
KASSERT(ch->ch_nparams == 0);
|
||||
|
||||
mutex_enter(&sc->sc_lock);
|
||||
if (ch->ch_index < 32) {
|
||||
EDMA_WRITE(sc, EDMA_IECR_REG, __BIT(ch->ch_index));
|
||||
} else {
|
||||
EDMA_WRITE(sc, EDMA_IECRH_REG, __BIT(ch->ch_index - 32));
|
||||
}
|
||||
ch->ch_callback = NULL;
|
||||
ch->ch_callbackarg = NULL;
|
||||
edma_bit_clr(sc->sc_dmamask, ch->ch_index);
|
||||
mutex_exit(&sc->sc_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a PaRAM entry. The driver artifically restricts the number
|
||||
* of PaRAM entries available for each channel to MAX_PARAM_PER_CHANNEL.
|
||||
* If the number of entries for the channel has been exceeded, or there
|
||||
* are no entries available, 0xffff is returned.
|
||||
*/
|
||||
uint16_t
|
||||
edma_param_alloc(struct edma_channel *ch)
|
||||
{
|
||||
struct edma_softc *sc = ch->ch_sc;
|
||||
uint16_t param_entry = 0xffff;
|
||||
int idx;
|
||||
|
||||
if (ch->ch_nparams == MAX_PARAM_PER_CHANNEL)
|
||||
return param_entry;
|
||||
|
||||
mutex_enter(&sc->sc_lock);
|
||||
for (idx = 0; idx < NUM_PARAM_SETS; idx++) {
|
||||
if (!edma_bit_isset(sc->sc_parammask, idx)) {
|
||||
param_entry = idx;
|
||||
edma_bit_set(sc->sc_parammask, idx);
|
||||
ch->ch_nparams++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_exit(&sc->sc_lock);
|
||||
|
||||
return param_entry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free a PaRAM entry allocated with edma_param_alloc
|
||||
*/
|
||||
void
|
||||
edma_param_free(struct edma_channel *ch, uint16_t param_entry)
|
||||
{
|
||||
struct edma_softc *sc = ch->ch_sc;
|
||||
|
||||
KASSERT(param_entry < NUM_PARAM_SETS);
|
||||
KASSERT(ch->ch_nparams > 0);
|
||||
KASSERT(edma_bit_isset(sc->sc_parammask, param_entry));
|
||||
|
||||
mutex_enter(&sc->sc_lock);
|
||||
edma_bit_clr(sc->sc_parammask, param_entry);
|
||||
ch->ch_nparams--;
|
||||
mutex_exit(&sc->sc_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update a PaRAM entry register set with caller-provided values
|
||||
*/
|
||||
void
|
||||
edma_set_param(struct edma_channel *ch, uint16_t param_entry,
|
||||
struct edma_param *ep)
|
||||
{
|
||||
struct edma_softc *sc = ch->ch_sc;
|
||||
|
||||
KASSERT(param_entry < NUM_PARAM_SETS);
|
||||
KASSERT(ch->ch_nparams > 0);
|
||||
KASSERT(edma_bit_isset(sc->sc_parammask, param_entry));
|
||||
|
||||
DPRINTF(1, (sc->sc_dev, "write param entry ch# %d pe %d: 0x%08x -> 0x%08x (%u, %u, %u)\n", ch->ch_index, param_entry, ep->ep_src, ep->ep_dst, ep->ep_acnt, ep->ep_bcnt, ep->ep_ccnt));
|
||||
edma_write_param(sc, param_entry, ep);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable a DMA channel: Point channel to the PaRam entry,
|
||||
* clear error if any, and only set the Event Enable bit.
|
||||
* The Even will either be generated by hardware, or with
|
||||
* edma_transfer_start()
|
||||
*/
|
||||
int
|
||||
edma_transfer_enable(struct edma_channel *ch, uint16_t param_entry)
|
||||
{
|
||||
struct edma_softc *sc = ch->ch_sc;
|
||||
bus_size_t off = (ch->ch_index < 32 ? 0 : 4);
|
||||
uint32_t bit = __BIT(ch->ch_index < 32 ?
|
||||
ch->ch_index : ch->ch_index - 32);
|
||||
|
||||
DPRINTF(1, (sc->sc_dev, "enable transfer ch# %d off %d bit %x pe %d\n", ch->ch_index, (int)off, bit, param_entry));
|
||||
|
||||
EDMA_WRITE(sc, EDMA_DCHMAP_REG(ch->ch_index),
|
||||
__SHIFTIN(param_entry, EDMA_DCHMAP_PAENTRY));
|
||||
|
||||
uint32_t ccerr = EDMA_READ(sc, EDMA_CCERR_REG);
|
||||
if (ccerr) {
|
||||
device_printf(sc->sc_dev, " !!! CCER %08x\n", ccerr);
|
||||
EDMA_WRITE(sc, EDMA_CCERRCLR_REG, ccerr);
|
||||
}
|
||||
|
||||
EDMA_WRITE(sc, EDMA_EESR_REG + off, bit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Software-start a DMA channel: Set the Event bit.
|
||||
*/
|
||||
int
|
||||
edma_transfer_start(struct edma_channel *ch)
|
||||
{
|
||||
struct edma_softc *sc = ch->ch_sc;
|
||||
bus_size_t off = (ch->ch_index < 32 ? 0 : 4);
|
||||
uint32_t bit = __BIT(ch->ch_index < 32 ?
|
||||
ch->ch_index : ch->ch_index - 32);
|
||||
|
||||
DPRINTF(1, (sc->sc_dev, "start transfer ch# %d off %d bit %x pe %d\n", ch->ch_index, (int)off, bit));
|
||||
|
||||
EDMA_WRITE(sc, EDMA_ESR_REG + off, bit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Halt a DMA transfer. Called after successfull transfer, or to abort
|
||||
* a transfer.
|
||||
*/
|
||||
void
|
||||
edma_halt(struct edma_channel *ch)
|
||||
{
|
||||
struct edma_softc *sc = ch->ch_sc;
|
||||
bus_size_t off = (ch->ch_index < 32 ? 0 : 4);
|
||||
uint32_t bit = __BIT(ch->ch_index < 32 ?
|
||||
ch->ch_index : ch->ch_index - 32);
|
||||
|
||||
EDMA_WRITE(sc, EDMA_EECR_REG + off, bit);
|
||||
EDMA_WRITE(sc, EDMA_ECR_REG + off, bit);
|
||||
EDMA_WRITE(sc, EDMA_SECR_REG + off, bit);
|
||||
EDMA_WRITE(sc, EDMA_EMCR_REG + off, bit);
|
||||
|
||||
EDMA_WRITE(sc, EDMA_DCHMAP_REG(ch->ch_index),
|
||||
__SHIFTIN(0, EDMA_DCHMAP_PAENTRY));
|
||||
}
|
||||
|
||||
uint8_t
|
||||
edma_channel_index(struct edma_channel *ch)
|
||||
{
|
||||
return ch->ch_index;
|
||||
}
|
||||
|
||||
void
|
||||
edma_dump(struct edma_channel *ch)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
uint16_t off;
|
||||
} regs[] = {
|
||||
{ "ER", EDMA_ER_REG },
|
||||
{ "ERH", EDMA_ERH_REG },
|
||||
{ "EER", EDMA_EER_REG },
|
||||
{ "EERH", EDMA_EERH_REG },
|
||||
{ "SER", EDMA_SER_REG },
|
||||
{ "SERH", EDMA_SERH_REG },
|
||||
{ "IER", EDMA_IER_REG },
|
||||
{ "IERH", EDMA_IERH_REG },
|
||||
{ "IPR", EDMA_IPR_REG },
|
||||
{ "IPRH", EDMA_IPRH_REG },
|
||||
{ "CCERR", EDMA_CCERR_REG },
|
||||
{ "CCSTAT", EDMA_CCSTAT_REG },
|
||||
{ "DRAE0", EDMA_DRAE_REG(0) },
|
||||
{ "DRAEH0", EDMA_DRAEH_REG(0) },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
struct edma_softc *sc = ch->ch_sc;
|
||||
int i;
|
||||
|
||||
for (i = 0; regs[i].name; i++) {
|
||||
device_printf(sc->sc_dev, "%s: %08x\n",
|
||||
regs[i].name, EDMA_READ(sc, regs[i].off));
|
||||
}
|
||||
device_printf(sc->sc_dev, "DCHMAP%d: %08x\n", ch->ch_index,
|
||||
EDMA_READ(sc, EDMA_DCHMAP_REG(ch->ch_index)));
|
||||
}
|
||||
|
||||
void
|
||||
edma_dump_param(struct edma_channel *ch, uint16_t param_entry)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
uint16_t off;
|
||||
} regs[] = {
|
||||
{ "OPT", EDMA_PARAM_OPT_REG(param_entry) },
|
||||
{ "CNT", EDMA_PARAM_CNT_REG(param_entry) },
|
||||
{ "DST", EDMA_PARAM_DST_REG(param_entry) },
|
||||
{ "BIDX", EDMA_PARAM_BIDX_REG(param_entry) },
|
||||
{ "LNK", EDMA_PARAM_LNK_REG(param_entry) },
|
||||
{ "CIDX", EDMA_PARAM_CIDX_REG(param_entry) },
|
||||
{ "CCNT", EDMA_PARAM_CCNT_REG(param_entry) },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
struct edma_softc *sc = ch->ch_sc;
|
||||
int i;
|
||||
|
||||
for (i = 0; regs[i].name; i++) {
|
||||
device_printf(sc->sc_dev, "%s%d: %08x\n",
|
||||
regs[i].name, param_entry, EDMA_READ(sc, regs[i].off));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
/* $NetBSD: ti_edma.h,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2014 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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 _TI_EDMA_H
|
||||
#define _TI_EDMA_H
|
||||
|
||||
#define EDMA_PID_REG 0x0000
|
||||
#define EDMA_CCCFG_REG 0x0004
|
||||
#define EDMA_CCCFG_MP_EXIST __BIT(25)
|
||||
#define EDMA_CCCFG_CHMAP_EXIST __BIT(24)
|
||||
#define EDMA_CCCFG_NUM_REGN __BITS(21,20)
|
||||
#define EDMA_CCCFG_NUM_EVQUEUE __BITS(18,16)
|
||||
#define EDMA_CCCFG_NUM_PAENTRY __BITS(14,12)
|
||||
#define EDMA_CCCFG_NUM_INTCH __BITS(10,8)
|
||||
#define EDMA_CCCFG_NUM_QDMACH __BITS(6,4)
|
||||
#define EDMA_CCCFG_NUM_DMACH __BITS(2,0)
|
||||
#define EDMA_SYSCONFIG_REG 0x0010
|
||||
#define EDMA_DCHMAP_REG(n) (0x0100 + 4 * (n))
|
||||
#define EDMA_DCHMAP_PAENTRY __BITS(13,5)
|
||||
#define EDMA_QCHMAP_REG(n) (0x0200 + 4 * (n))
|
||||
#define EDMA_DMAQNUM_REG(n) (0x0240 + 4 * (n))
|
||||
#define EDMA_QDMAQNUM_REG 0x0260
|
||||
#define EDMA_QUEPRI_REG 0x0284
|
||||
#define EDMA_EMR_REG 0x0300
|
||||
#define EDMA_EMRH_REG 0x0304
|
||||
#define EDMA_EMCR_REG 0x0308
|
||||
#define EDMA_EMCRH_REG 0x030c
|
||||
#define EDMA_QEMR_REG 0x0310
|
||||
#define EDMA_QEMRC_REG 0x0314
|
||||
#define EDMA_CCERR_REG 0x0318
|
||||
#define EDMA_CCERRCLR_REG 0x031c
|
||||
#define EDMA_EEVAL_REG 0x0320
|
||||
#define EDMA_DRAE_REG(n) (0x0340 + 8 * (n))
|
||||
#define EDMA_DRAEH_REG(n) (0x0340 + 8 * (n) + 4)
|
||||
#define EDMA_QRAE_REG(n) (0x0380 + 4 * (n))
|
||||
#define EDMA_QE_REG(q, e) (0x0400 + 0x40 * (q) + 4 * (e))
|
||||
#define EDMA_QSTAT_REG(n) (0x0600 + 4 * (n))
|
||||
#define EDMA_QWMTHRA_REG 0x0620
|
||||
#define EDMA_CCSTAT_REG 0x0640
|
||||
#define EDMA_MPFAR_REG 0x0800
|
||||
#define EDMA_MPFSR_REG 0x0804
|
||||
#define EDMA_MPFCR_REG 0x0808
|
||||
#define EDMA_MPPAG_REG 0x080c
|
||||
#define EDMA_MPPA_REG(n) (0x0810 + 4 * (n))
|
||||
#define EDMA_ER_REG 0x1000
|
||||
#define EDMA_ERH_REG 0x1004
|
||||
#define EDMA_ECR_REG 0x1008
|
||||
#define EDMA_ECRH_REG 0x100c
|
||||
#define EDMA_ESR_REG 0x1010
|
||||
#define EDMA_ESRH_REG 0x1014
|
||||
#define EDMA_CER_REG 0x1018
|
||||
#define EDMA_CERH_REG 0x101c
|
||||
#define EDMA_EER_REG 0x1020
|
||||
#define EDMA_EERH_REG 0x1024
|
||||
#define EDMA_EECR_REG 0x1028
|
||||
#define EDMA_EECRH_REG 0x102c
|
||||
#define EDMA_EESR_REG 0x1030
|
||||
#define EDMA_EESRH_REG 0x1034
|
||||
#define EDMA_SER_REG 0x1038
|
||||
#define EDMA_SERH_REG 0x103c
|
||||
#define EDMA_SECR_REG 0x1040
|
||||
#define EDMA_SECRH_REG 0x1044
|
||||
#define EDMA_IER_REG 0x1050
|
||||
#define EDMA_IERH_REG 0x1054
|
||||
#define EDMA_IECR_REG 0x1058
|
||||
#define EDMA_IECRH_REG 0x105c
|
||||
#define EDMA_IESR_REG 0x1060
|
||||
#define EDMA_IESRH_REG 0x1064
|
||||
#define EDMA_IPR_REG 0x1068
|
||||
#define EDMA_IPRH_REG 0x106c
|
||||
#define EDMA_ICR_REG 0x1070
|
||||
#define EDMA_ICRH_REG 0x1074
|
||||
#define EDMA_IEVAL_REG 0x1078
|
||||
#define EDMA_IEVAL_EVAL __BIT(0)
|
||||
#define EDMA_QER_REG 0x1080
|
||||
#define EDMA_QEER_REG 0x1084
|
||||
#define EDMA_QEECR_REG 0x1088
|
||||
#define EDMA_QEESR_REG 0x108c
|
||||
#define EDMA_QSER_REG 0x1090
|
||||
#define EDMA_QSECR_REG 0x1094
|
||||
|
||||
#define EDMA_PARAM_BASE(n) (0x4000 + 0x20 * (n))
|
||||
#define EDMA_PARAM_OPT_REG(n) (EDMA_PARAM_BASE(n) + 0x00)
|
||||
#define EDMA_PARAM_OPT_PRIV __BIT(31)
|
||||
#define EDMA_PARAM_OPT_PRIVID __BITS(27,24)
|
||||
#define EDMA_PARAM_OPT_ITCCHEN __BIT(23)
|
||||
#define EDMA_PARAM_OPT_TCCHEN __BIT(22)
|
||||
#define EDMA_PARAM_OPT_ITCINTEN __BIT(21)
|
||||
#define EDMA_PARAM_OPT_TCINTEN __BIT(20)
|
||||
#define EDMA_PARAM_OPT_TCC __BITS(17,12)
|
||||
#define EDMA_PARAM_OPT_TCCMODE __BIT(11)
|
||||
#define EDMA_PARAM_OPT_FWID __BITS(10,8)
|
||||
#define EDMA_PARAM_OPT_STATIC __BIT(3)
|
||||
#define EDMA_PARAM_OPT_SYNCDIM __BIT(2)
|
||||
#define EDMA_PARAM_OPT_DAM __BIT(1)
|
||||
#define EDMA_PARAM_OPT_SAM __BIT(0)
|
||||
#define EDMA_PARAM_SRC_REG(n) (EDMA_PARAM_BASE(n) + 0x04)
|
||||
#define EDMA_PARAM_CNT_REG(n) (EDMA_PARAM_BASE(n) + 0x08)
|
||||
#define EDMA_PARAM_CNT_BCNT __BITS(31,16)
|
||||
#define EDMA_PARAM_CNT_ACNT __BITS(15,0)
|
||||
#define EDMA_PARAM_DST_REG(n) (EDMA_PARAM_BASE(n) + 0x0c)
|
||||
#define EDMA_PARAM_BIDX_REG(n) (EDMA_PARAM_BASE(n) + 0x10)
|
||||
#define EDMA_PARAM_BIDX_DSTBIDX __BITS(31,16)
|
||||
#define EDMA_PARAM_BIDX_SRCBIDX __BITS(15,0)
|
||||
#define EDMA_PARAM_LNK_REG(n) (EDMA_PARAM_BASE(n) + 0x14)
|
||||
#define EDMA_PARAM_LNK_BCNTRLD __BITS(31,16)
|
||||
#define EDMA_PARAM_LNK_LINK __BITS(15,0)
|
||||
#define EDMA_PARAM_CIDX_REG(n) (EDMA_PARAM_BASE(n) + 0x18)
|
||||
#define EDMA_PARAM_CIDX_DSTCIDX __BITS(31,16)
|
||||
#define EDMA_PARAM_CIDX_SRCCIDX __BITS(15,0)
|
||||
#define EDMA_PARAM_CCNT_REG(n) (EDMA_PARAM_BASE(n) + 0x1c)
|
||||
#define EDMA_PARAM_CCNT_CCNT __BITS(15,0)
|
||||
|
||||
enum edma_type {
|
||||
EDMA_TYPE_DMA,
|
||||
EDMA_TYPE_QDMA
|
||||
};
|
||||
|
||||
struct edma_param {
|
||||
uint32_t ep_opt;
|
||||
uint32_t ep_src;
|
||||
uint32_t ep_dst;
|
||||
uint16_t ep_bcnt;
|
||||
uint16_t ep_acnt;
|
||||
uint16_t ep_dstbidx;
|
||||
uint16_t ep_srcbidx;
|
||||
uint16_t ep_bcntrld;
|
||||
uint16_t ep_link;
|
||||
uint16_t ep_dstcidx;
|
||||
uint16_t ep_srccidx;
|
||||
uint16_t ep_ccnt;
|
||||
};
|
||||
|
||||
struct edma_channel;
|
||||
|
||||
struct edma_channel *edma_channel_alloc(enum edma_type, unsigned int,
|
||||
void (*)(void *), void *);
|
||||
void edma_channel_free(struct edma_channel *);
|
||||
uint16_t edma_param_alloc(struct edma_channel *);
|
||||
void edma_param_free(struct edma_channel *, uint16_t);
|
||||
void edma_set_param(struct edma_channel *, uint16_t, struct edma_param *);
|
||||
int edma_transfer_enable(struct edma_channel *, uint16_t);
|
||||
int edma_transfer_start(struct edma_channel *);
|
||||
void edma_halt(struct edma_channel *);
|
||||
uint8_t edma_channel_index(struct edma_channel *);
|
||||
void edma_dump(struct edma_channel *);
|
||||
void edma_dump_param(struct edma_channel *, uint16_t);
|
||||
|
||||
#endif /* !_TI_EDMA_H */
|
|
@ -0,0 +1,157 @@
|
|||
/* $NetBSD: ti_ehci.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015-2019 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: ti_ehci.c,v 1.1.2.2 2019/11/27 13:46:44 martin 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>
|
||||
|
||||
#define TI_EHCI_NPORTS 3
|
||||
|
||||
static int ti_ehci_match(device_t, cfdata_t, void *);
|
||||
static void ti_ehci_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL2_NEW(ti_ehci, sizeof(struct ehci_softc),
|
||||
ti_ehci_match, ti_ehci_attach, NULL,
|
||||
ehci_activate, NULL, ehci_childdet);
|
||||
|
||||
static int
|
||||
ti_ehci_match(device_t parent, cfdata_t cf, void *aux)
|
||||
{
|
||||
const char * const compatible[] = {
|
||||
"ti,ehci-omap",
|
||||
NULL
|
||||
};
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_ehci_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;
|
||||
}
|
||||
|
||||
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_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");
|
||||
|
||||
/* Enable PHYs */
|
||||
for (n = 0; n < TI_EHCI_NPORTS; n++) {
|
||||
phy = fdtbus_phy_get_index(phandle, n);
|
||||
if (phy && fdtbus_phy_enable(phy, true) != 0) {
|
||||
aprint_error(": couldn't enable phy\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
pmf_device_register1(self, NULL, NULL, ehci_shutdown);
|
||||
|
||||
sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
/* $NetBSD: ti_fb.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015-2019 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_wsdisplay_compat.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_fb.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
#include <dev/fdt/fdt_port.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drmfb.h>
|
||||
|
||||
#include <arm/ti/ti_lcdc.h>
|
||||
|
||||
static int ti_fb_match(device_t, cfdata_t, void *);
|
||||
static void ti_fb_attach(device_t, device_t, void *);
|
||||
|
||||
static bool ti_fb_shutdown(device_t, int);
|
||||
|
||||
struct ti_fb_softc {
|
||||
struct drmfb_softc sc_drmfb;
|
||||
device_t sc_dev;
|
||||
struct tilcdc_framebuffer *sc_fb;
|
||||
struct tilcdcfb_attach_args sc_tfa;
|
||||
};
|
||||
|
||||
static paddr_t ti_fb_mmapfb(struct drmfb_softc *, off_t, int);
|
||||
static int ti_fb_ioctl(struct drmfb_softc *, u_long, void *, int,
|
||||
lwp_t *);
|
||||
|
||||
static const struct drmfb_params tifb_drmfb_params = {
|
||||
.dp_mmapfb = ti_fb_mmapfb,
|
||||
.dp_ioctl = ti_fb_ioctl,
|
||||
|
||||
};
|
||||
|
||||
CFATTACH_DECL_NEW(ti_fb, sizeof(struct ti_fb_softc),
|
||||
ti_fb_match, ti_fb_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
ti_fb_match(device_t parent, cfdata_t cf, void *aux)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_fb_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_fb_softc * const sc = device_private(self);
|
||||
struct tilcdcfb_attach_args * const tfa = aux;
|
||||
int error;
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_tfa = *tfa;
|
||||
sc->sc_fb = to_tilcdc_framebuffer(tfa->tfa_fb_helper->fb);
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal("\n");
|
||||
|
||||
#ifdef WSDISPLAY_MULTICONS
|
||||
prop_dictionary_t dict = device_properties(self);
|
||||
const bool is_console = true;
|
||||
prop_dictionary_set_bool(dict, "is_console", is_console);
|
||||
#endif
|
||||
|
||||
const struct drmfb_attach_args da = {
|
||||
.da_dev = self,
|
||||
.da_fb_helper = tfa->tfa_fb_helper,
|
||||
.da_fb_sizes = &tfa->tfa_fb_sizes,
|
||||
.da_fb_vaddr = sc->sc_fb->obj->vaddr,
|
||||
.da_fb_linebytes = tfa->tfa_fb_linebytes,
|
||||
.da_params = &tifb_drmfb_params,
|
||||
};
|
||||
|
||||
error = drmfb_attach(&sc->sc_drmfb, &da);
|
||||
if (error) {
|
||||
aprint_error_dev(self, "failed to attach drmfb: %d\n", error);
|
||||
return;
|
||||
}
|
||||
|
||||
pmf_device_register1(self, NULL, NULL, ti_fb_shutdown);
|
||||
}
|
||||
|
||||
static bool
|
||||
ti_fb_shutdown(device_t self, int flags)
|
||||
{
|
||||
struct ti_fb_softc * const sc = device_private(self);
|
||||
|
||||
return drmfb_shutdown(&sc->sc_drmfb, flags);
|
||||
}
|
||||
|
||||
static paddr_t
|
||||
ti_fb_mmapfb(struct drmfb_softc *sc, off_t off, int prot)
|
||||
{
|
||||
struct ti_fb_softc * const tfb_sc = (struct ti_fb_softc *)sc;
|
||||
struct drm_gem_cma_object *obj = tfb_sc->sc_fb->obj;
|
||||
|
||||
KASSERT(off >= 0);
|
||||
KASSERT(off < obj->dmasize);
|
||||
|
||||
return bus_dmamem_mmap(obj->dmat, obj->dmasegs, 1, off, prot,
|
||||
BUS_DMA_PREFETCHABLE);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_fb_ioctl(struct drmfb_softc *sc, u_long cmd, void *data, int flag,
|
||||
lwp_t *l)
|
||||
{
|
||||
struct wsdisplayio_bus_id *busid;
|
||||
struct wsdisplayio_fbinfo *fbi;
|
||||
struct rasops_info *ri = &sc->sc_genfb.vd.active->scr_ri;
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
case WSDISPLAYIO_GET_BUSID:
|
||||
busid = data;
|
||||
busid->bus_type = WSDISPLAYIO_BUS_SOC;
|
||||
return 0;
|
||||
case WSDISPLAYIO_GTYPE:
|
||||
*(u_int *)data = WSDISPLAY_TYPE_GENFB;
|
||||
return 0;
|
||||
case WSDISPLAYIO_GET_FBINFO:
|
||||
fbi = data;
|
||||
error = wsdisplayio_get_fbinfo(ri, fbi);
|
||||
fbi->fbi_flags |= WSFB_VRAM_IS_RAM;
|
||||
return error;
|
||||
default:
|
||||
return EPASSTHROUGH;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,538 @@
|
|||
/* $NetBSD: ti_gpio.c,v 1.3.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: ti_gpio.c,v 1.3.2.2 2019/11/27 13:46:44 martin 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 <sys/bitops.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
#include <dev/gpio/gpiovar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
#define TI_GPIO_NPINS 32
|
||||
|
||||
enum ti_gpio_type {
|
||||
TI_GPIO_OMAP3,
|
||||
TI_GPIO_OMAP4,
|
||||
TI_NGPIO
|
||||
};
|
||||
|
||||
enum {
|
||||
GPIO_IRQSTATUS1,
|
||||
GPIO_IRQENABLE1, /* OMAP3 */
|
||||
GPIO_IRQENABLE1_SET, /* OMAP4 */
|
||||
GPIO_IRQENABLE1_CLR, /* OMAP4 */
|
||||
GPIO_OE,
|
||||
GPIO_DATAIN,
|
||||
GPIO_DATAOUT,
|
||||
GPIO_LEVELDETECT0,
|
||||
GPIO_LEVELDETECT1,
|
||||
GPIO_RISINGDETECT,
|
||||
GPIO_FALLINGDETECT,
|
||||
GPIO_CLEARDATAOUT,
|
||||
GPIO_SETDATAOUT,
|
||||
GPIO_NREG
|
||||
};
|
||||
|
||||
static const u_int ti_gpio_regmap[TI_NGPIO][GPIO_NREG] = {
|
||||
[TI_GPIO_OMAP3] = {
|
||||
[GPIO_IRQSTATUS1] = 0x18,
|
||||
[GPIO_IRQENABLE1] = 0x1c,
|
||||
[GPIO_OE] = 0x34,
|
||||
[GPIO_DATAIN] = 0x38,
|
||||
[GPIO_DATAOUT] = 0x3c,
|
||||
[GPIO_LEVELDETECT0] = 0x40,
|
||||
[GPIO_LEVELDETECT1] = 0x44,
|
||||
[GPIO_RISINGDETECT] = 0x48,
|
||||
[GPIO_FALLINGDETECT] = 0x4c,
|
||||
[GPIO_CLEARDATAOUT] = 0x90,
|
||||
[GPIO_SETDATAOUT] = 0x94,
|
||||
},
|
||||
[TI_GPIO_OMAP4] = {
|
||||
[GPIO_IRQSTATUS1] = 0x2c,
|
||||
[GPIO_IRQENABLE1_SET] = 0x34,
|
||||
[GPIO_IRQENABLE1_CLR] = 0x38,
|
||||
[GPIO_OE] = 0x134,
|
||||
[GPIO_DATAIN] = 0x138,
|
||||
[GPIO_DATAOUT] = 0x13c,
|
||||
[GPIO_LEVELDETECT0] = 0x140,
|
||||
[GPIO_LEVELDETECT1] = 0x144,
|
||||
[GPIO_RISINGDETECT] = 0x148,
|
||||
[GPIO_FALLINGDETECT] = 0x14c,
|
||||
[GPIO_CLEARDATAOUT] = 0x190,
|
||||
[GPIO_SETDATAOUT] = 0x194,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct of_compat_data compat_data[] = {
|
||||
{ "ti,omap3-gpio", TI_GPIO_OMAP3 },
|
||||
{ "ti,omap4-gpio", TI_GPIO_OMAP4 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
struct ti_gpio_intr {
|
||||
u_int intr_pin;
|
||||
int (*intr_func)(void *);
|
||||
void *intr_arg;
|
||||
bool intr_mpsafe;
|
||||
};
|
||||
|
||||
struct ti_gpio_softc {
|
||||
device_t sc_dev;
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
kmutex_t sc_lock;
|
||||
enum ti_gpio_type sc_type;
|
||||
const char *sc_modname;
|
||||
void *sc_ih;
|
||||
|
||||
struct gpio_chipset_tag sc_gp;
|
||||
gpio_pin_t sc_pins[TI_GPIO_NPINS];
|
||||
bool sc_pinout[TI_GPIO_NPINS];
|
||||
struct ti_gpio_intr sc_intr[TI_GPIO_NPINS];
|
||||
device_t sc_gpiodev;
|
||||
};
|
||||
|
||||
struct ti_gpio_pin {
|
||||
struct ti_gpio_softc *pin_sc;
|
||||
u_int pin_nr;
|
||||
int pin_flags;
|
||||
bool pin_actlo;
|
||||
};
|
||||
|
||||
#define RD4(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, ti_gpio_regmap[(sc)->sc_type][(reg)])
|
||||
#define WR4(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, ti_gpio_regmap[(sc)->sc_type][(reg)], (val))
|
||||
|
||||
static int ti_gpio_match(device_t, cfdata_t, void *);
|
||||
static void ti_gpio_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_gpio, sizeof(struct ti_gpio_softc),
|
||||
ti_gpio_match, ti_gpio_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
ti_gpio_ctl(struct ti_gpio_softc *sc, u_int pin, int flags)
|
||||
{
|
||||
uint32_t oe;
|
||||
|
||||
KASSERT(mutex_owned(&sc->sc_lock));
|
||||
|
||||
oe = RD4(sc, GPIO_OE);
|
||||
if (flags & GPIO_PIN_INPUT)
|
||||
oe |= __BIT(pin);
|
||||
else if (flags & GPIO_PIN_OUTPUT)
|
||||
oe &= ~__BIT(pin);
|
||||
WR4(sc, GPIO_OE, oe);
|
||||
|
||||
sc->sc_pinout[pin] = (flags & GPIO_PIN_OUTPUT) != 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *
|
||||
ti_gpio_acquire(device_t dev, const void *data, size_t len, int flags)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = device_private(dev);
|
||||
struct ti_gpio_pin *gpin;
|
||||
const u_int *gpio = data;
|
||||
int error;
|
||||
|
||||
if (len != 12)
|
||||
return NULL;
|
||||
|
||||
const uint8_t pin = be32toh(gpio[1]) & 0xff;
|
||||
const bool actlo = be32toh(gpio[2]) & 1;
|
||||
|
||||
if (pin >= __arraycount(sc->sc_pins))
|
||||
return NULL;
|
||||
|
||||
mutex_enter(&sc->sc_lock);
|
||||
error = ti_gpio_ctl(sc, pin, flags);
|
||||
mutex_exit(&sc->sc_lock);
|
||||
|
||||
if (error != 0)
|
||||
return NULL;
|
||||
|
||||
gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP);
|
||||
gpin->pin_sc = sc;
|
||||
gpin->pin_nr = pin;
|
||||
gpin->pin_flags = flags;
|
||||
gpin->pin_actlo = actlo;
|
||||
|
||||
return gpin;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_gpio_release(device_t dev, void *priv)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = device_private(dev);
|
||||
struct ti_gpio_pin *pin = priv;
|
||||
|
||||
mutex_enter(&sc->sc_lock);
|
||||
ti_gpio_ctl(pin->pin_sc, pin->pin_nr, GPIO_PIN_INPUT);
|
||||
mutex_exit(&sc->sc_lock);
|
||||
|
||||
kmem_free(pin, sizeof(*pin));
|
||||
}
|
||||
|
||||
static int
|
||||
ti_gpio_read(device_t dev, void *priv, bool raw)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = device_private(dev);
|
||||
struct ti_gpio_pin *pin = priv;
|
||||
uint32_t data;
|
||||
int val;
|
||||
|
||||
KASSERT(sc == pin->pin_sc);
|
||||
|
||||
const uint32_t data_mask = __BIT(pin->pin_nr);
|
||||
|
||||
/* No lock required for reads */
|
||||
if (sc->sc_pinout[pin->pin_nr])
|
||||
data = RD4(sc, GPIO_DATAOUT);
|
||||
else
|
||||
data = RD4(sc, GPIO_DATAIN);
|
||||
val = __SHIFTOUT(data, data_mask);
|
||||
if (!raw && pin->pin_actlo)
|
||||
val = !val;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_gpio_write(device_t dev, void *priv, int val, bool raw)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = device_private(dev);
|
||||
struct ti_gpio_pin *pin = priv;
|
||||
|
||||
KASSERT(sc == pin->pin_sc);
|
||||
|
||||
const uint32_t data_mask = __BIT(pin->pin_nr);
|
||||
|
||||
if (!raw && pin->pin_actlo)
|
||||
val = !val;
|
||||
|
||||
const u_int data_reg = val ? GPIO_SETDATAOUT : GPIO_CLEARDATAOUT;
|
||||
|
||||
WR4(sc, data_reg, data_mask);
|
||||
}
|
||||
|
||||
static struct fdtbus_gpio_controller_func ti_gpio_funcs = {
|
||||
.acquire = ti_gpio_acquire,
|
||||
.release = ti_gpio_release,
|
||||
.read = ti_gpio_read,
|
||||
.write = ti_gpio_write,
|
||||
};
|
||||
|
||||
static void
|
||||
ti_gpio_intr_disestablish(device_t dev, void *ih)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = device_private(dev);
|
||||
struct ti_gpio_intr *intr = ih;
|
||||
const u_int pin = intr->intr_pin;
|
||||
const uint32_t pin_mask = __BIT(pin);
|
||||
uint32_t val;
|
||||
|
||||
/* Disable interrupts */
|
||||
if (sc->sc_type == TI_GPIO_OMAP3) {
|
||||
val = RD4(sc, GPIO_IRQENABLE1);
|
||||
WR4(sc, GPIO_IRQENABLE1, val & ~pin_mask);
|
||||
} else {
|
||||
WR4(sc, GPIO_IRQENABLE1_CLR, pin_mask);
|
||||
}
|
||||
|
||||
intr->intr_func = NULL;
|
||||
intr->intr_arg = NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
ti_gpio_intr_establish(device_t dev, u_int *specifier, int ipl, int flags,
|
||||
int (*func)(void *), void *arg)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = device_private(dev);
|
||||
uint32_t val;
|
||||
|
||||
/* 1st cell is the pin */
|
||||
/* 2nd cell is flags */
|
||||
const u_int pin = be32toh(specifier[0]);
|
||||
const u_int type = be32toh(specifier[2]) & 0xf;
|
||||
|
||||
if (ipl != IPL_VM || pin >= __arraycount(sc->sc_pins))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Enabling both high and low level triggers will cause the GPIO
|
||||
* controller to always assert the interrupt.
|
||||
*/
|
||||
if ((type & (FDT_INTR_TYPE_LOW_LEVEL|FDT_INTR_TYPE_HIGH_LEVEL)) ==
|
||||
(FDT_INTR_TYPE_LOW_LEVEL|FDT_INTR_TYPE_HIGH_LEVEL))
|
||||
return NULL;
|
||||
|
||||
if (sc->sc_intr[pin].intr_func != NULL)
|
||||
return NULL;
|
||||
|
||||
/* Set pin as input */
|
||||
if (ti_gpio_ctl(sc, pin, GPIO_PIN_INPUT) != 0)
|
||||
return NULL;
|
||||
|
||||
sc->sc_intr[pin].intr_pin = pin;
|
||||
sc->sc_intr[pin].intr_func = func;
|
||||
sc->sc_intr[pin].intr_arg = arg;
|
||||
sc->sc_intr[pin].intr_mpsafe = (flags & FDT_INTR_MPSAFE) != 0;
|
||||
|
||||
const uint32_t pin_mask = __BIT(pin);
|
||||
|
||||
/* Configure triggers */
|
||||
val = RD4(sc, GPIO_LEVELDETECT0);
|
||||
if ((type & FDT_INTR_TYPE_LOW_LEVEL) != 0)
|
||||
val |= pin_mask;
|
||||
else
|
||||
val &= ~pin_mask;
|
||||
WR4(sc, GPIO_LEVELDETECT0, val);
|
||||
|
||||
val = RD4(sc, GPIO_LEVELDETECT1);
|
||||
if ((type & FDT_INTR_TYPE_HIGH_LEVEL) != 0)
|
||||
val |= pin_mask;
|
||||
else
|
||||
val &= ~pin_mask;
|
||||
WR4(sc, GPIO_LEVELDETECT1, val);
|
||||
|
||||
val = RD4(sc, GPIO_RISINGDETECT);
|
||||
if ((type & FDT_INTR_TYPE_POS_EDGE) != 0)
|
||||
val |= pin_mask;
|
||||
else
|
||||
val &= ~pin_mask;
|
||||
WR4(sc, GPIO_RISINGDETECT, val);
|
||||
|
||||
val = RD4(sc, GPIO_FALLINGDETECT);
|
||||
if ((type & FDT_INTR_TYPE_NEG_EDGE) != 0)
|
||||
val |= pin_mask;
|
||||
else
|
||||
val &= ~pin_mask;
|
||||
WR4(sc, GPIO_FALLINGDETECT, val);
|
||||
|
||||
/* Enable interrupts */
|
||||
if (sc->sc_type == TI_GPIO_OMAP3) {
|
||||
val = RD4(sc, GPIO_IRQENABLE1);
|
||||
WR4(sc, GPIO_IRQENABLE1, val | pin_mask);
|
||||
} else {
|
||||
WR4(sc, GPIO_IRQENABLE1_SET, pin_mask);
|
||||
}
|
||||
|
||||
return &sc->sc_intr[pin];
|
||||
}
|
||||
|
||||
static bool
|
||||
ti_gpio_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = device_private(dev);
|
||||
|
||||
/* 1st cell is the pin */
|
||||
/* 2nd cell is flags */
|
||||
const u_int pin = be32toh(specifier[0]);
|
||||
|
||||
if (pin >= __arraycount(sc->sc_pins))
|
||||
return false;
|
||||
|
||||
snprintf(buf, buflen, "%s pin %d", sc->sc_modname, pin);
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct fdtbus_interrupt_controller_func ti_gpio_intrfuncs = {
|
||||
.establish = ti_gpio_intr_establish,
|
||||
.disestablish = ti_gpio_intr_disestablish,
|
||||
.intrstr = ti_gpio_intrstr,
|
||||
};
|
||||
|
||||
static int
|
||||
ti_gpio_pin_read(void *priv, int pin)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = priv;
|
||||
uint32_t data;
|
||||
int val;
|
||||
|
||||
KASSERT(pin < __arraycount(sc->sc_pins));
|
||||
|
||||
const uint32_t data_mask = __BIT(pin);
|
||||
|
||||
data = RD4(sc, GPIO_DATAIN);
|
||||
val = __SHIFTOUT(data, data_mask);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_gpio_pin_write(void *priv, int pin, int val)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = priv;
|
||||
|
||||
KASSERT(pin < __arraycount(sc->sc_pins));
|
||||
|
||||
const u_int data_reg = val ? GPIO_SETDATAOUT : GPIO_CLEARDATAOUT;
|
||||
const uint32_t data_mask = __BIT(pin);
|
||||
|
||||
WR4(sc, data_reg, data_mask);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_gpio_pin_ctl(void *priv, int pin, int flags)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = priv;
|
||||
|
||||
KASSERT(pin < __arraycount(sc->sc_pins));
|
||||
|
||||
mutex_enter(&sc->sc_lock);
|
||||
ti_gpio_ctl(sc, pin, flags);
|
||||
mutex_exit(&sc->sc_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_gpio_attach_ports(struct ti_gpio_softc *sc)
|
||||
{
|
||||
struct gpio_chipset_tag *gp = &sc->sc_gp;
|
||||
struct gpiobus_attach_args gba;
|
||||
u_int pin;
|
||||
|
||||
gp->gp_cookie = sc;
|
||||
gp->gp_pin_read = ti_gpio_pin_read;
|
||||
gp->gp_pin_write = ti_gpio_pin_write;
|
||||
gp->gp_pin_ctl = ti_gpio_pin_ctl;
|
||||
|
||||
for (pin = 0; pin < __arraycount(sc->sc_pins); pin++) {
|
||||
sc->sc_pins[pin].pin_num = pin;
|
||||
sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
|
||||
sc->sc_pins[pin].pin_state = ti_gpio_pin_read(sc, pin);
|
||||
}
|
||||
|
||||
memset(&gba, 0, sizeof(gba));
|
||||
gba.gba_gc = gp;
|
||||
gba.gba_pins = sc->sc_pins;
|
||||
gba.gba_npins = __arraycount(sc->sc_pins);
|
||||
sc->sc_gpiodev = config_found_ia(sc->sc_dev, "gpiobus", &gba, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_gpio_intr(void *priv)
|
||||
{
|
||||
struct ti_gpio_softc * const sc = priv;
|
||||
uint32_t status;
|
||||
u_int bit;
|
||||
int rv = 0;
|
||||
|
||||
status = RD4(sc, GPIO_IRQSTATUS1);
|
||||
WR4(sc, GPIO_IRQSTATUS1, status);
|
||||
|
||||
while ((bit = ffs32(status)) != 0) {
|
||||
const u_int pin = bit - 1;
|
||||
const uint32_t pin_mask = __BIT(pin);
|
||||
struct ti_gpio_intr *intr = &sc->sc_intr[pin];
|
||||
status &= ~pin_mask;
|
||||
if (intr->intr_func == NULL)
|
||||
continue;
|
||||
if (!intr->intr_mpsafe)
|
||||
KERNEL_LOCK(1, curlwp);
|
||||
rv |= intr->intr_func(intr->intr_arg);
|
||||
if (!intr->intr_mpsafe)
|
||||
KERNEL_UNLOCK_ONE(curlwp);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int
|
||||
ti_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
|
||||
ti_gpio_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_gpio_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;
|
||||
}
|
||||
if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
|
||||
aprint_error(": couldn't decode interrupt\n");
|
||||
return;
|
||||
}
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\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;
|
||||
}
|
||||
sc->sc_type = of_search_compatible(phandle, compat_data)->data;
|
||||
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
|
||||
sc->sc_modname = fdtbus_get_string(phandle, "ti,hwmods");
|
||||
if (sc->sc_modname == NULL)
|
||||
sc->sc_modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods");
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": GPIO (%s)\n", sc->sc_modname);
|
||||
|
||||
fdtbus_register_gpio_controller(self, phandle, &ti_gpio_funcs);
|
||||
|
||||
ti_gpio_attach_ports(sc);
|
||||
|
||||
sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, FDT_INTR_MPSAFE,
|
||||
ti_gpio_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);
|
||||
fdtbus_register_interrupt_controller(self, phandle, &ti_gpio_intrfuncs);
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/* $NetBSD: ti_gpmc.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: ti_gpmc.c,v 1.1.2.2 2019/11/27 13:46:44 martin 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/kmem.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
static int ti_gpmc_match(device_t, cfdata_t, void *);
|
||||
static void ti_gpmc_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_gpmc, 0, ti_gpmc_match, ti_gpmc_attach, NULL, NULL);
|
||||
|
||||
static const char * compatible[] = {
|
||||
"ti,omap3430-gpmc",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int
|
||||
ti_gpmc_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
|
||||
ti_gpmc_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": GPMC\n");
|
||||
|
||||
fdt_add_bus(self, phandle, faa);
|
||||
}
|
|
@ -0,0 +1,710 @@
|
|||
/* $NetBSD: ti_iic.c,v 1.4.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 Manuel Bouyer. 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2012 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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: ti_iic.c,v 1.4.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/proc.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/ti/ti_prcm.h>
|
||||
#include <arm/ti/ti_iicreg.h>
|
||||
|
||||
#ifndef OMAP2_I2C_SLAVE_ADDR
|
||||
#define OMAP2_I2C_SLAVE_ADDR 0x01
|
||||
#endif
|
||||
|
||||
#define OMAP2_I2C_FIFOBYTES(fd) (8 << (fd))
|
||||
|
||||
#ifdef I2CDEBUG
|
||||
#define DPRINTF(args) printf args
|
||||
#else
|
||||
#define DPRINTF(args)
|
||||
#endif
|
||||
|
||||
enum ti_iic_type {
|
||||
TI_IIC_OMAP3,
|
||||
TI_IIC_OMAP4,
|
||||
TI_NTYPES
|
||||
};
|
||||
|
||||
enum {
|
||||
I2C_SYSC,
|
||||
I2C_IRQSTATUS_RAW,
|
||||
I2C_IRQSTATUS,
|
||||
I2C_IRQENABLE, /* OMAP3 */
|
||||
I2C_IRQENABLE_SET, /* OMAP4 */
|
||||
I2C_IRQENABLE_CLR, /* OMAP4 */
|
||||
I2C_SYSS,
|
||||
I2C_BUF,
|
||||
I2C_CNT,
|
||||
I2C_DATA,
|
||||
I2C_CON,
|
||||
I2C_OA,
|
||||
I2C_SA,
|
||||
I2C_PSC,
|
||||
I2C_SCLL,
|
||||
I2C_SCLH,
|
||||
I2C_BUFSTAT,
|
||||
TI_NREGS
|
||||
};
|
||||
|
||||
static const u_int ti_iic_regmap[TI_NTYPES][TI_NREGS] = {
|
||||
[TI_IIC_OMAP3] = {
|
||||
[I2C_SYSC] = 0x20,
|
||||
[I2C_IRQSTATUS_RAW] = 0x08,
|
||||
[I2C_IRQSTATUS] = 0x08,
|
||||
[I2C_IRQENABLE] = 0x04,
|
||||
[I2C_SYSS] = 0x10,
|
||||
[I2C_BUF] = 0x14,
|
||||
[I2C_CNT] = 0x18,
|
||||
[I2C_DATA] = 0x1c,
|
||||
[I2C_CON] = 0x24,
|
||||
[I2C_OA] = 0x28,
|
||||
[I2C_SA] = 0x2c,
|
||||
[I2C_PSC] = 0x30,
|
||||
[I2C_SCLL] = 0x34,
|
||||
[I2C_SCLH] = 0x38,
|
||||
[I2C_BUFSTAT] = 0x40,
|
||||
},
|
||||
[TI_IIC_OMAP4] = {
|
||||
[I2C_SYSC] = 0x10,
|
||||
[I2C_IRQSTATUS_RAW] = 0x24,
|
||||
[I2C_IRQSTATUS] = 0x28,
|
||||
[I2C_IRQENABLE_SET] = 0x2c,
|
||||
[I2C_IRQENABLE_CLR] = 0x30,
|
||||
[I2C_SYSS] = 0x90,
|
||||
[I2C_BUF] = 0x94,
|
||||
[I2C_CNT] = 0x98,
|
||||
[I2C_DATA] = 0x9c,
|
||||
[I2C_CON] = 0xa4,
|
||||
[I2C_OA] = 0xa8,
|
||||
[I2C_SA] = 0xac,
|
||||
[I2C_PSC] = 0xb0,
|
||||
[I2C_SCLL] = 0xb4,
|
||||
[I2C_SCLH] = 0xb8,
|
||||
[I2C_BUFSTAT] = 0xc0,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct of_compat_data compat_data[] = {
|
||||
/* compatible type */
|
||||
{ "ti,omap3-i2c", TI_IIC_OMAP3 },
|
||||
{ "ti,omap4-i2c", TI_IIC_OMAP4 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* operation in progress */
|
||||
typedef enum {
|
||||
TI_I2CREAD,
|
||||
TI_I2CWRITE,
|
||||
TI_I2CDONE,
|
||||
TI_I2CERROR
|
||||
} ti_i2cop_t;
|
||||
|
||||
struct ti_iic_softc {
|
||||
device_t sc_dev;
|
||||
struct i2c_controller sc_ic;
|
||||
kmutex_t sc_lock;
|
||||
device_t sc_i2cdev;
|
||||
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ioh;
|
||||
|
||||
enum ti_iic_type sc_type;
|
||||
|
||||
void *sc_ih;
|
||||
kmutex_t sc_mtx;
|
||||
kcondvar_t sc_cv;
|
||||
ti_i2cop_t sc_op;
|
||||
int sc_opflags;
|
||||
int sc_buflen;
|
||||
int sc_bufidx;
|
||||
char *sc_buf;
|
||||
|
||||
bool sc_busy;
|
||||
|
||||
int sc_rxthres;
|
||||
int sc_txthres;
|
||||
};
|
||||
|
||||
#define I2C_READ_REG(sc, reg) \
|
||||
bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][(reg)])
|
||||
#define I2C_READ_DATA(sc) \
|
||||
bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][I2C_DATA])
|
||||
#define I2C_WRITE_REG(sc, reg, val) \
|
||||
bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][(reg)], (val))
|
||||
#define I2C_WRITE_DATA(sc, val) \
|
||||
bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, ti_iic_regmap[(sc)->sc_type][I2C_DATA], (val))
|
||||
|
||||
static int ti_iic_match(device_t, cfdata_t, void *);
|
||||
static void ti_iic_attach(device_t, device_t, void *);
|
||||
|
||||
static int ti_iic_intr(void *);
|
||||
|
||||
static int ti_iic_acquire_bus(void *, int);
|
||||
static void ti_iic_release_bus(void *, int);
|
||||
static int ti_iic_exec(void *, i2c_op_t, i2c_addr_t, const void *,
|
||||
size_t, void *, size_t, int);
|
||||
|
||||
static int ti_iic_reset(struct ti_iic_softc *);
|
||||
static int ti_iic_op(struct ti_iic_softc *, i2c_addr_t, ti_i2cop_t,
|
||||
uint8_t *, size_t, int);
|
||||
static void ti_iic_handle_intr(struct ti_iic_softc *, uint32_t);
|
||||
static void ti_iic_do_read(struct ti_iic_softc *, uint32_t);
|
||||
static void ti_iic_do_write(struct ti_iic_softc *, uint32_t);
|
||||
|
||||
static int ti_iic_wait(struct ti_iic_softc *, uint16_t, uint16_t, int);
|
||||
static uint32_t ti_iic_stat(struct ti_iic_softc *, uint32_t);
|
||||
static int ti_iic_flush(struct ti_iic_softc *);
|
||||
|
||||
static i2c_tag_t ti_iic_get_tag(device_t);
|
||||
|
||||
static const struct fdtbus_i2c_controller_func ti_iic_funcs = {
|
||||
.get_tag = ti_iic_get_tag,
|
||||
};
|
||||
|
||||
CFATTACH_DECL_NEW(ti_iic, sizeof(struct ti_iic_softc),
|
||||
ti_iic_match, ti_iic_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
ti_iic_match(device_t parent, cfdata_t match, void *opaque)
|
||||
{
|
||||
struct fdt_attach_args * const faa = opaque;
|
||||
|
||||
return of_match_compat_data(faa->faa_phandle, compat_data);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_iic_attach(device_t parent, device_t self, void *opaque)
|
||||
{
|
||||
struct ti_iic_softc *sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = opaque;
|
||||
const int phandle = faa->faa_phandle;
|
||||
int fifodepth, fifo;
|
||||
const char *modname;
|
||||
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 (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_iot = faa->faa_bst;
|
||||
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
|
||||
mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NET);
|
||||
cv_init(&sc->sc_cv, "tiiic");
|
||||
sc->sc_ic.ic_cookie = sc;
|
||||
sc->sc_ic.ic_acquire_bus = ti_iic_acquire_bus;
|
||||
sc->sc_ic.ic_release_bus = ti_iic_release_bus;
|
||||
sc->sc_ic.ic_exec = ti_iic_exec;
|
||||
|
||||
if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
sc->sc_type = of_search_compatible(phandle, compat_data)->data;
|
||||
|
||||
sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_NET, 0,
|
||||
ti_iic_intr, sc);
|
||||
if (sc->sc_ih == NULL) {
|
||||
aprint_error(": couldn't establish interrupt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
modname = fdtbus_get_string(phandle, "ti,hwmods");
|
||||
if (modname == NULL)
|
||||
modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods");
|
||||
|
||||
fifodepth = I2C_BUFSTAT_FIFODEPTH(I2C_READ_REG(sc, I2C_BUFSTAT));
|
||||
fifo = OMAP2_I2C_FIFOBYTES(fifodepth);
|
||||
sc->sc_rxthres = sc->sc_txthres = fifo >> 1;
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": I2C controller (%s), %d-bytes FIFO\n", modname, fifo);
|
||||
|
||||
ti_iic_reset(sc);
|
||||
ti_iic_flush(sc);
|
||||
|
||||
fdtbus_register_i2c_controller(self, phandle, &ti_iic_funcs);
|
||||
|
||||
fdtbus_attach_i2cbus(self, phandle, &sc->sc_ic, iicbus_print);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_iic_intr(void *arg)
|
||||
{
|
||||
struct ti_iic_softc *sc = arg;
|
||||
uint32_t stat;
|
||||
|
||||
mutex_enter(&sc->sc_mtx);
|
||||
DPRINTF(("ti_iic_intr opflags=%#x\n", sc->sc_opflags));
|
||||
if ((sc->sc_opflags & I2C_F_POLL) == 0) {
|
||||
stat = I2C_READ_REG(sc, I2C_IRQSTATUS);
|
||||
DPRINTF(("ti_iic_intr pre handle sc->sc_op eq %#x\n", sc->sc_op));
|
||||
ti_iic_handle_intr(sc, stat);
|
||||
I2C_WRITE_REG(sc, I2C_IRQSTATUS, stat);
|
||||
if (sc->sc_op == TI_I2CERROR || sc->sc_op == TI_I2CDONE) {
|
||||
DPRINTF(("ti_iic_intr post handle sc->sc_op %#x\n", sc->sc_op));
|
||||
cv_broadcast(&sc->sc_cv);
|
||||
}
|
||||
}
|
||||
mutex_exit(&sc->sc_mtx);
|
||||
DPRINTF(("ti_iic_intr status 0x%x\n", stat));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ti_iic_acquire_bus(void *opaque, int flags)
|
||||
{
|
||||
struct ti_iic_softc *sc = opaque;
|
||||
|
||||
mutex_enter(&sc->sc_lock);
|
||||
while (sc->sc_busy)
|
||||
cv_wait(&sc->sc_cv, &sc->sc_lock);
|
||||
sc->sc_busy = true;
|
||||
mutex_exit(&sc->sc_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_iic_release_bus(void *opaque, int flags)
|
||||
{
|
||||
struct ti_iic_softc *sc = opaque;
|
||||
|
||||
mutex_enter(&sc->sc_lock);
|
||||
sc->sc_busy = false;
|
||||
cv_broadcast(&sc->sc_cv);
|
||||
mutex_exit(&sc->sc_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_iic_exec(void *opaque, i2c_op_t op, i2c_addr_t addr,
|
||||
const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
|
||||
{
|
||||
struct ti_iic_softc *sc = opaque;
|
||||
int err;
|
||||
|
||||
DPRINTF(("ti_iic_exec: op 0x%x cmdlen %zd len %zd flags 0x%x\n",
|
||||
op, cmdlen, len, flags));
|
||||
|
||||
if (cmdlen > 0) {
|
||||
err = ti_iic_op(sc, addr, TI_I2CWRITE,
|
||||
__UNCONST(cmdbuf), cmdlen,
|
||||
(I2C_OP_READ_P(op) ? 0 : I2C_F_STOP) | flags);
|
||||
if (err)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (I2C_OP_STOP_P(op))
|
||||
flags |= I2C_F_STOP;
|
||||
|
||||
/*
|
||||
* I2C controller doesn't allow for zero-byte transfers.
|
||||
*/
|
||||
if (len == 0) {
|
||||
err = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (I2C_OP_READ_P(op)) {
|
||||
err = ti_iic_op(sc, addr, TI_I2CREAD, buf, len, flags);
|
||||
} else {
|
||||
err = ti_iic_op(sc, addr, TI_I2CWRITE, buf, len, flags);
|
||||
}
|
||||
|
||||
done:
|
||||
if (err)
|
||||
ti_iic_reset(sc);
|
||||
|
||||
ti_iic_flush(sc);
|
||||
|
||||
DPRINTF(("ti_iic_exec: done %d\n", err));
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
ti_iic_reset(struct ti_iic_softc *sc)
|
||||
{
|
||||
uint32_t psc, scll, sclh;
|
||||
int i;
|
||||
|
||||
DPRINTF(("ti_iic_reset\n"));
|
||||
|
||||
/* Disable */
|
||||
I2C_WRITE_REG(sc, I2C_CON, 0);
|
||||
/* Soft reset */
|
||||
I2C_WRITE_REG(sc, I2C_SYSC, I2C_SYSC_SRST);
|
||||
delay(1000);
|
||||
/* enable so that we can check for reset complete */
|
||||
I2C_WRITE_REG(sc, I2C_CON, I2C_CON_EN);
|
||||
delay(1000);
|
||||
for (i = 0; i < 1000; i++) { /* 1s delay for reset */
|
||||
if (I2C_READ_REG(sc, I2C_SYSS) & I2C_SYSS_RDONE)
|
||||
break;
|
||||
}
|
||||
/* Disable again */
|
||||
I2C_WRITE_REG(sc, I2C_CON, 0);
|
||||
delay(50000);
|
||||
|
||||
if (i >= 1000) {
|
||||
aprint_error_dev(sc->sc_dev, ": couldn't reset module\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* XXX standard speed only */
|
||||
if (sc->sc_type == TI_IIC_OMAP3) {
|
||||
psc = (96000000 / 19200000) - 1;
|
||||
scll = sclh = (19200000 / (2 * 100000)) - 6;
|
||||
} else {
|
||||
psc = 3;
|
||||
scll = 53;
|
||||
sclh = 55;
|
||||
}
|
||||
|
||||
/* Clocks */
|
||||
I2C_WRITE_REG(sc, I2C_PSC, psc);
|
||||
I2C_WRITE_REG(sc, I2C_SCLL, scll);
|
||||
I2C_WRITE_REG(sc, I2C_SCLH, sclh);
|
||||
|
||||
/* Own I2C address */
|
||||
I2C_WRITE_REG(sc, I2C_OA, OMAP2_I2C_SLAVE_ADDR);
|
||||
|
||||
/* 5 bytes fifo */
|
||||
I2C_WRITE_REG(sc, I2C_BUF,
|
||||
I2C_BUF_RXTRSH(sc->sc_rxthres) | I2C_BUF_TXTRSH(sc->sc_txthres));
|
||||
|
||||
/* Enable */
|
||||
I2C_WRITE_REG(sc, I2C_CON, I2C_CON_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ti_iic_op(struct ti_iic_softc *sc, i2c_addr_t addr, ti_i2cop_t op,
|
||||
uint8_t *buf, size_t buflen, int flags)
|
||||
{
|
||||
uint16_t con, stat, mask;
|
||||
int err, retry;
|
||||
|
||||
KASSERT(op == TI_I2CREAD || op == TI_I2CWRITE);
|
||||
DPRINTF(("ti_iic_op: addr %#x op %#x buf %p buflen %#x flags %#x\n",
|
||||
addr, op, buf, (unsigned int) buflen, flags));
|
||||
|
||||
mask = I2C_IRQSTATUS_ARDY | I2C_IRQSTATUS_NACK | I2C_IRQSTATUS_AL;
|
||||
if (op == TI_I2CREAD) {
|
||||
mask |= I2C_IRQSTATUS_RDR | I2C_IRQSTATUS_RRDY;
|
||||
} else {
|
||||
mask |= I2C_IRQSTATUS_XDR | I2C_IRQSTATUS_XRDY;
|
||||
}
|
||||
|
||||
err = ti_iic_wait(sc, I2C_IRQSTATUS_BB, 0, flags);
|
||||
if (err) {
|
||||
DPRINTF(("ti_iic_op: wait error %d\n", err));
|
||||
return err;
|
||||
}
|
||||
|
||||
con = I2C_CON_EN;
|
||||
con |= I2C_CON_MST;
|
||||
con |= I2C_CON_STT;;
|
||||
if (flags & I2C_F_STOP)
|
||||
con |= I2C_CON_STP;
|
||||
if (addr & ~0x7f)
|
||||
con |= I2C_CON_XSA;
|
||||
if (op == TI_I2CWRITE)
|
||||
con |= I2C_CON_TRX;
|
||||
|
||||
mutex_enter(&sc->sc_mtx);
|
||||
sc->sc_op = op;
|
||||
sc->sc_opflags = flags;
|
||||
sc->sc_buf = buf;
|
||||
sc->sc_buflen = buflen;
|
||||
sc->sc_bufidx = 0;
|
||||
|
||||
I2C_WRITE_REG(sc, I2C_CON, I2C_CON_EN | I2C_CON_MST | I2C_CON_STP);
|
||||
DPRINTF(("ti_iic_op: op %d con 0x%x ", op, con));
|
||||
I2C_WRITE_REG(sc, I2C_CNT, buflen);
|
||||
I2C_WRITE_REG(sc, I2C_SA, (addr & I2C_SA_MASK));
|
||||
DPRINTF(("SA 0x%x len %d\n", I2C_READ_REG(sc, I2C_SA), I2C_READ_REG(sc, I2C_CNT)));
|
||||
|
||||
if ((flags & I2C_F_POLL) == 0 || sc->sc_type == TI_IIC_OMAP3) {
|
||||
/* clear any pending interrupt */
|
||||
I2C_WRITE_REG(sc, I2C_IRQSTATUS,
|
||||
I2C_READ_REG(sc, I2C_IRQSTATUS));
|
||||
/* and enable */
|
||||
if (sc->sc_type == TI_IIC_OMAP4) {
|
||||
I2C_WRITE_REG(sc, I2C_IRQENABLE_SET, mask);
|
||||
} else {
|
||||
I2C_WRITE_REG(sc, I2C_IRQENABLE, mask);
|
||||
}
|
||||
}
|
||||
/* start transfer */
|
||||
I2C_WRITE_REG(sc, I2C_CON, con);
|
||||
|
||||
if ((flags & I2C_F_POLL) == 0) {
|
||||
/* and wait for completion */
|
||||
DPRINTF(("ti_iic_op waiting, op %#x\n", sc->sc_op));
|
||||
while (sc->sc_op == op) {
|
||||
if (cv_timedwait(&sc->sc_cv, &sc->sc_mtx,
|
||||
mstohz(5000)) == EWOULDBLOCK) {
|
||||
/* timeout */
|
||||
op = TI_I2CERROR;
|
||||
}
|
||||
}
|
||||
DPRINTF(("ti_iic_op waiting done, op %#x\n", sc->sc_op));
|
||||
|
||||
/* disable interrupts */
|
||||
if (sc->sc_type == TI_IIC_OMAP4) {
|
||||
I2C_WRITE_REG(sc, I2C_IRQENABLE_CLR, 0xffff);
|
||||
} else {
|
||||
I2C_WRITE_REG(sc, I2C_IRQENABLE, 0);
|
||||
}
|
||||
} else {
|
||||
/* poll for completion */
|
||||
DPRINTF(("ti_iic_op polling, op %x\n", sc->sc_op));
|
||||
while (sc->sc_op == op) {
|
||||
stat = ti_iic_stat(sc, mask);
|
||||
DPRINTF(("ti_iic_op stat 0x%x\n", stat));
|
||||
if (stat == 0) {
|
||||
/* timeout */
|
||||
sc->sc_op = TI_I2CERROR;
|
||||
} else {
|
||||
ti_iic_handle_intr(sc, stat);
|
||||
}
|
||||
I2C_WRITE_REG(sc, I2C_IRQSTATUS, stat);
|
||||
}
|
||||
DPRINTF(("ti_iic_op polling done, op now %x\n", sc->sc_op));
|
||||
}
|
||||
mutex_exit(&sc->sc_mtx);
|
||||
retry = 10000;
|
||||
I2C_WRITE_REG(sc, I2C_CON, 0);
|
||||
while (I2C_READ_REG(sc, I2C_CON) & I2C_CON_MST) {
|
||||
delay(100);
|
||||
if (--retry == 0)
|
||||
break;
|
||||
}
|
||||
return (sc->sc_op == TI_I2CDONE) ? 0 : EIO;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_iic_handle_intr(struct ti_iic_softc *sc, uint32_t stat)
|
||||
{
|
||||
KASSERT(mutex_owned(&sc->sc_mtx));
|
||||
KASSERT(stat != 0);
|
||||
DPRINTF(("ti_iic_handle_intr stat %#x\n", stat));
|
||||
|
||||
if (stat &
|
||||
(I2C_IRQSTATUS_NACK|I2C_IRQSTATUS_AL)) {
|
||||
sc->sc_op = TI_I2CERROR;
|
||||
return;
|
||||
}
|
||||
if (stat & I2C_IRQSTATUS_ARDY) {
|
||||
sc->sc_op = TI_I2CDONE;
|
||||
return;
|
||||
}
|
||||
if (sc->sc_op == TI_I2CREAD)
|
||||
ti_iic_do_read(sc, stat);
|
||||
else if (sc->sc_op == TI_I2CWRITE)
|
||||
ti_iic_do_write(sc, stat);
|
||||
else
|
||||
return;
|
||||
}
|
||||
void
|
||||
ti_iic_do_read(struct ti_iic_softc *sc, uint32_t stat)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
KASSERT(mutex_owned(&sc->sc_mtx));
|
||||
DPRINTF(("ti_iic_do_read stat %#x\n", stat));
|
||||
if (stat & I2C_IRQSTATUS_RDR) {
|
||||
len = I2C_READ_REG(sc, I2C_BUFSTAT);
|
||||
len = I2C_BUFSTAT_RXSTAT(len);
|
||||
DPRINTF(("ti_iic_do_read receive drain len %d left %d\n",
|
||||
len, I2C_READ_REG(sc, I2C_CNT)));
|
||||
} else if (stat & I2C_IRQSTATUS_RRDY) {
|
||||
len = sc->sc_rxthres + 1;
|
||||
DPRINTF(("ti_iic_do_read receive len %d left %d\n",
|
||||
len, I2C_READ_REG(sc, I2C_CNT)));
|
||||
}
|
||||
for (;
|
||||
sc->sc_bufidx < sc->sc_buflen && len > 0;
|
||||
sc->sc_bufidx++, len--) {
|
||||
sc->sc_buf[sc->sc_bufidx] = I2C_READ_DATA(sc);
|
||||
DPRINTF(("ti_iic_do_read got b[%d]=0x%x\n", sc->sc_bufidx,
|
||||
sc->sc_buf[sc->sc_bufidx]));
|
||||
}
|
||||
DPRINTF(("ti_iic_do_read done\n"));
|
||||
}
|
||||
|
||||
void
|
||||
ti_iic_do_write(struct ti_iic_softc *sc, uint32_t stat)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
DPRINTF(("ti_iic_do_write stat %#x\n", stat));
|
||||
KASSERT(mutex_owned(&sc->sc_mtx));
|
||||
if (stat & I2C_IRQSTATUS_XDR) {
|
||||
len = I2C_READ_REG(sc, I2C_BUFSTAT);
|
||||
len = I2C_BUFSTAT_TXSTAT(len);
|
||||
DPRINTF(("ti_iic_do_write xmit drain len %d left %d\n",
|
||||
len, I2C_READ_REG(sc, I2C_CNT)));
|
||||
} else if (stat & I2C_IRQSTATUS_XRDY) {
|
||||
len = sc->sc_txthres + 1;
|
||||
DPRINTF(("ti_iic_do_write xmit len %d left %d\n",
|
||||
len, I2C_READ_REG(sc, I2C_CNT)));
|
||||
}
|
||||
for (;
|
||||
sc->sc_bufidx < sc->sc_buflen && len > 0;
|
||||
sc->sc_bufidx++, len--) {
|
||||
DPRINTF(("ti_iic_do_write send b[%d]=0x%x\n",
|
||||
sc->sc_bufidx, sc->sc_buf[sc->sc_bufidx]));
|
||||
I2C_WRITE_DATA(sc, sc->sc_buf[sc->sc_bufidx]);
|
||||
}
|
||||
DPRINTF(("ti_iic_do_write done\n"));
|
||||
}
|
||||
|
||||
static int
|
||||
ti_iic_wait(struct ti_iic_softc *sc, uint16_t mask, uint16_t val, int flags)
|
||||
{
|
||||
int retry = 10;
|
||||
uint16_t v;
|
||||
DPRINTF(("ti_iic_wait mask %#x val %#x flags %#x\n", mask, val, flags));
|
||||
|
||||
while (((v = I2C_READ_REG(sc, I2C_IRQSTATUS_RAW)) & mask) != val) {
|
||||
--retry;
|
||||
if (retry == 0) {
|
||||
aprint_error_dev(sc->sc_dev, ": wait timeout, "
|
||||
"mask = %#x val = %#x stat = %#x\n",
|
||||
mask, val, v);
|
||||
return EBUSY;
|
||||
}
|
||||
if (flags & I2C_F_POLL) {
|
||||
delay(50000);
|
||||
} else {
|
||||
kpause("tiiic", false, mstohz(50), NULL);
|
||||
}
|
||||
}
|
||||
DPRINTF(("ti_iic_wait done retry %#x\n", retry));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
ti_iic_stat(struct ti_iic_softc *sc, uint32_t mask)
|
||||
{
|
||||
uint32_t v;
|
||||
int retry = 500;
|
||||
DPRINTF(("ti_iic_wait mask %#x\n", mask));
|
||||
while (--retry > 0) {
|
||||
v = I2C_READ_REG(sc, I2C_IRQSTATUS_RAW) & mask;
|
||||
if (v != 0)
|
||||
break;
|
||||
delay(100);
|
||||
}
|
||||
DPRINTF(("ti_iic_wait done retry %#x\n", retry));
|
||||
return v;
|
||||
}
|
||||
|
||||
static int
|
||||
ti_iic_flush(struct ti_iic_softc *sc)
|
||||
{
|
||||
DPRINTF(("ti_iic_flush\n"));
|
||||
#if 0
|
||||
int retry = 1000;
|
||||
uint16_t v;
|
||||
|
||||
while ((v = I2C_READ_REG(sc, I2C_IRQSTATUS_RAW)) & I2C_IRQSTATUS_RRDY) {
|
||||
if (--retry == 0) {
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
": flush timeout, stat = %#x\n", v);
|
||||
return EBUSY;
|
||||
}
|
||||
(void)I2C_READ_DATA(sc);
|
||||
delay(1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
I2C_WRITE_REG(sc, I2C_CNT, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static i2c_tag_t
|
||||
ti_iic_get_tag(device_t dev)
|
||||
{
|
||||
struct ti_iic_softc * const sc = device_private(dev);
|
||||
|
||||
return &sc->sc_ic;
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/* $NetBSD: ti_iicreg.h,v 1.3.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 Manuel Bouyer. 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 _TI_IICREG_H
|
||||
#define _TI_IICREG_H
|
||||
|
||||
#define I2C_SYSC_CLKACTIVITY_OCP 0x0010
|
||||
#define I2C_SYSC_CLKACTIVITY_SYSTEM 0x0020
|
||||
#define I2C_SYSC_IDLE_MASK 0x0018
|
||||
#define I2C_SYSC_IDLE_FORCE 0x0000
|
||||
#define I2C_SYSC_IDLE_SMART 0x0010
|
||||
#define I2C_SYSC_IDLE_NONE 0x0008
|
||||
#define I2C_SYSC_ENAWAKEUP 0x0004
|
||||
#define I2C_SYSC_SRST 0x0002
|
||||
#define I2C_SYSC_AUTOIDLE 0x0001
|
||||
|
||||
#define I2C_IRQSTATUS_XDR 0x4000
|
||||
#define I2C_IRQSTATUS_RDR 0x2000
|
||||
#define I2C_IRQSTATUS_BB 0x1000
|
||||
#define I2C_IRQSTATUS_ROVR 0x0800
|
||||
#define I2C_IRQSTATUS_XUDF 0x0400
|
||||
#define I2C_IRQSTATUS_AAS 0x0200
|
||||
#define I2C_IRQSTATUS_BF 0x0100
|
||||
#define I2C_IRQSTATUS_AERR 0x0080
|
||||
#define I2C_IRQSTATUS_STC 0x0040
|
||||
#define I2C_IRQSTATUS_GC 0x0020
|
||||
#define I2C_IRQSTATUS_XRDY 0x0010
|
||||
#define I2C_IRQSTATUS_RRDY 0x0008
|
||||
#define I2C_IRQSTATUS_ARDY 0x0004
|
||||
#define I2C_IRQSTATUS_NACK 0x0002
|
||||
#define I2C_IRQSTATUS_AL 0x0001
|
||||
|
||||
#define I2C_DMARXENABLE 0x0001
|
||||
|
||||
#define I2C_DMATXENABLE 0x0001
|
||||
|
||||
#define I2C_SYSS_RDONE 0x0001
|
||||
|
||||
#define I2C_BUF_RDMA_EN 0x8000
|
||||
#define I2C_BUF_RXFIFO_CLR 0x4000
|
||||
#define I2C_BUF_RXTRSH_MASK 0x3f00
|
||||
#define I2C_BUF_RXTRSH(x) ((x) << 8)
|
||||
#define I2C_BUF_XDMA_EN 0x0080
|
||||
#define I2C_BUF_TXFIFO_CLR 0x0040
|
||||
#define I2C_BUF_TXTRSH_MASK 0x003f
|
||||
#define I2C_BUF_TXTRSH(x) ((x) << 0)
|
||||
|
||||
#define I2C_CNT_MASK 0xffff
|
||||
|
||||
#define I2C_DATA_MASK 0x00ff
|
||||
|
||||
#define I2C_CON_EN 0x8000
|
||||
#define I2C_CON_STB 0x0800
|
||||
#define I2C_CON_MST 0x0400
|
||||
#define I2C_CON_TRX 0x0200
|
||||
#define I2C_CON_XSA 0x0100
|
||||
#define I2C_CON_XOA0 0x0080
|
||||
#define I2C_CON_XOA1 0x0040
|
||||
#define I2C_CON_XOA2 0x0020
|
||||
#define I2C_CON_XOA3 0x0010
|
||||
#define I2C_CON_STP 0x0002
|
||||
#define I2C_CON_STT 0x0001
|
||||
|
||||
#define I2C_OA_MASK 0x03ff
|
||||
|
||||
#define I2C_SA_MASK 0x03ff
|
||||
|
||||
#define I2C_PSC_MASK 0x000f
|
||||
|
||||
#define I2C_SCLL_MASK 0x000f
|
||||
|
||||
#define I2C_SCLH_MASK 0x000f
|
||||
|
||||
#define I2C_BUFSTAT_FIFODEPTH(x) (((x) >> 14) & 0x03)
|
||||
#define I2C_BUFSTAT_RXSTAT(x) (((x) >> 8) & 0x3f)
|
||||
#define I2C_BUFSTAT_TXSTAT(x) (((x) >> 0) & 0x3f)
|
||||
|
||||
#define I2C_ACTOA_OA3_ACT 0x0008
|
||||
#define I2C_ACTOA_OA2_ACT 0x0004
|
||||
#define I2C_ACTOA_OA1_ACT 0x0002
|
||||
#define I2C_ACTOA_OA0_ACT 0x0001
|
||||
|
||||
#endif /* _TI_IICREG_H */
|
|
@ -0,0 +1,664 @@
|
|||
/* $NetBSD: ti_lcdc.c,v 1.3.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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 <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_lcdc.c,v 1.3.2.2 2019/11/27 13:46:44 martin 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/conf.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
#include <uvm/uvm_object.h>
|
||||
#include <uvm/uvm_device.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
#include <dev/fdt/fdt_port.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
#include <arm/ti/ti_lcdc.h>
|
||||
#include <arm/ti/ti_lcdcreg.h>
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,am33xx-tilcdc",
|
||||
NULL
|
||||
};
|
||||
|
||||
enum {
|
||||
TILCDC_PORT_OUTPUT = 0,
|
||||
};
|
||||
|
||||
static int tilcdc_match(device_t, cfdata_t, void *);
|
||||
static void tilcdc_attach(device_t, device_t, void *);
|
||||
|
||||
static int tilcdc_set_busid(struct drm_device *, struct drm_master *);
|
||||
|
||||
static int tilcdc_load(struct drm_device *, unsigned long);
|
||||
static int tilcdc_unload(struct drm_device *);
|
||||
|
||||
static struct drm_driver tilcdc_driver = {
|
||||
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
|
||||
.dev_priv_size = 0,
|
||||
.load = tilcdc_load,
|
||||
.unload = tilcdc_unload,
|
||||
|
||||
.gem_free_object = drm_gem_cma_free_object,
|
||||
.mmap_object = drm_gem_or_legacy_mmap_object,
|
||||
.gem_uvm_ops = &drm_gem_cma_uvm_ops,
|
||||
|
||||
.dumb_create = drm_gem_cma_dumb_create,
|
||||
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
|
||||
.dumb_destroy = drm_gem_dumb_destroy,
|
||||
|
||||
.name = DRIVER_NAME,
|
||||
.desc = DRIVER_DESC,
|
||||
.date = DRIVER_DATE,
|
||||
.major = DRIVER_MAJOR,
|
||||
.minor = DRIVER_MINOR,
|
||||
.patchlevel = DRIVER_PATCHLEVEL,
|
||||
|
||||
.set_busid = tilcdc_set_busid,
|
||||
};
|
||||
|
||||
CFATTACH_DECL_NEW(ti_lcdc, sizeof(struct tilcdc_softc),
|
||||
tilcdc_match, tilcdc_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
tilcdc_mode_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
||||
int x, int y, int atomic)
|
||||
{
|
||||
struct tilcdc_crtc *mixer_crtc = to_tilcdc_crtc(crtc);
|
||||
struct tilcdc_softc * const sc = mixer_crtc->sc;
|
||||
struct tilcdc_framebuffer *sfb = atomic?
|
||||
to_tilcdc_framebuffer(fb) :
|
||||
to_tilcdc_framebuffer(crtc->primary->fb);
|
||||
|
||||
const uint32_t paddr = (uint32_t)sfb->obj->dmamap->dm_segs[0].ds_addr;
|
||||
const u_int psize = sfb->obj->dmamap->dm_segs[0].ds_len;
|
||||
|
||||
/* Framebuffer start address */
|
||||
WR4(sc, LCD_LCDDMA_FB0_BASE, paddr);
|
||||
WR4(sc, LCD_LCDDMA_FB0_CEILING, paddr + psize - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tilcdc_destroy(struct drm_crtc *crtc)
|
||||
{
|
||||
drm_crtc_cleanup(crtc);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_funcs tilcdc_crtc_funcs = {
|
||||
.set_config = drm_crtc_helper_set_config,
|
||||
.destroy = tilcdc_destroy,
|
||||
};
|
||||
|
||||
static void
|
||||
tilcdc_dpms(struct drm_crtc *crtc, int mode)
|
||||
{
|
||||
}
|
||||
|
||||
static bool
|
||||
tilcdc_mode_fixup(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
#if 0
|
||||
adjusted_mode->hskew = mode->hsync_end - mode->hsync_start;
|
||||
adjusted_mode->flags |= DRM_MODE_FLAG_HSKEW;
|
||||
|
||||
adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PHSYNC);
|
||||
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
|
||||
adjusted_mode->flags |= DRM_MODE_FLAG_PHSYNC;
|
||||
else
|
||||
adjusted_mode->flags |= DRM_MODE_FLAG_NHSYNC;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
tilcdc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode, int x, int y,
|
||||
struct drm_framebuffer *old_fb)
|
||||
{
|
||||
struct tilcdc_crtc *mixer_crtc = to_tilcdc_crtc(crtc);
|
||||
struct tilcdc_softc * const sc = mixer_crtc->sc;
|
||||
int clk_div, div, diff, best_diff;
|
||||
uint32_t val;
|
||||
|
||||
const u_int hspw = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
|
||||
const u_int hbp = adjusted_mode->crtc_htotal - adjusted_mode->crtc_hsync_end;
|
||||
const u_int hfp = adjusted_mode->crtc_hsync_start - adjusted_mode->crtc_hdisplay;
|
||||
const u_int vspw = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
|
||||
const u_int vbp = adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vsync_end;
|
||||
const u_int vfp = adjusted_mode->crtc_vsync_start - adjusted_mode->crtc_vdisplay;
|
||||
|
||||
const u_int rate = clk_get_rate(sc->sc_clk);
|
||||
|
||||
clk_div = 255;
|
||||
best_diff = -1;
|
||||
for (div = 2; div < 255; div++) {
|
||||
const int pixel_clock = (rate / div) / 1000;
|
||||
diff = abs(adjusted_mode->crtc_clock - pixel_clock);
|
||||
if (best_diff == -1 || diff < best_diff) {
|
||||
best_diff = diff;
|
||||
clk_div = div;
|
||||
}
|
||||
}
|
||||
if (clk_div == 255) {
|
||||
device_printf(sc->sc_dev, "couldn't configure pixel clock (%u)\n",
|
||||
adjusted_mode->crtc_clock);
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
val = CTRL_RASTER_MODE |
|
||||
(clk_div << CTRL_DIV_SHIFT);
|
||||
WR4(sc, LCD_CTRL, val);
|
||||
|
||||
val = RASTER_TIMING_0_HFP(hfp) |
|
||||
RASTER_TIMING_0_HBP(hbp) |
|
||||
RASTER_TIMING_0_HSW(hspw) |
|
||||
RASTER_TIMING_0_PPL(adjusted_mode->hdisplay);
|
||||
WR4(sc, LCD_RASTER_TIMING_0, val);
|
||||
|
||||
val = RASTER_TIMING_1_VFP(vfp) |
|
||||
RASTER_TIMING_1_VBP(vbp) |
|
||||
RASTER_TIMING_1_VSW(vspw) |
|
||||
RASTER_TIMING_1_LPP(adjusted_mode->vdisplay);
|
||||
WR4(sc, LCD_RASTER_TIMING_1, val);
|
||||
|
||||
val = RASTER_TIMING_2_HFP(hfp) |
|
||||
RASTER_TIMING_2_HBP(hbp) |
|
||||
RASTER_TIMING_2_HSW(hspw) |
|
||||
RASTER_TIMING_2_LPP(adjusted_mode->vdisplay);
|
||||
/* XXX TDA HDMI TX */
|
||||
val |= RASTER_TIMING_2_IPC;
|
||||
val |= RASTER_TIMING_2_PHSVS;
|
||||
val |= RASTER_TIMING_2_PHSVS_RISE;
|
||||
val |= RASTER_TIMING_2_ACB(255);
|
||||
val |= RASTER_TIMING_2_ACBI(0);
|
||||
WR4(sc, LCD_RASTER_TIMING_2, val);
|
||||
|
||||
val = (4 << LCDDMA_CTRL_BURST_SIZE_SHIFT) |
|
||||
(0 << LCDDMA_CTRL_TH_FIFO_RDY_SHIFT) |
|
||||
LCDDMA_CTRL_FB0_ONLY;
|
||||
WR4(sc, LCD_LCDDMA_CTRL, val);
|
||||
|
||||
/* XXX TDA HDMI TX */
|
||||
val = RASTER_CTRL_LCDTFT |
|
||||
RASTER_CTRL_TFT24 |
|
||||
RASTER_CTRL_TFT24_UNPACKED |
|
||||
RASTER_CTRL_REQDLY(0x80) |
|
||||
RASTER_CTRL_PALMODE_DATA_ONLY;
|
||||
WR4(sc, LCD_RASTER_CTRL, val);
|
||||
|
||||
tilcdc_mode_do_set_base(crtc, old_fb, x, y, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tilcdc_mode_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
struct drm_framebuffer *old_fb)
|
||||
{
|
||||
tilcdc_mode_do_set_base(crtc, old_fb, x, y, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tilcdc_mode_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
||||
int x, int y, enum mode_set_atomic state)
|
||||
{
|
||||
tilcdc_mode_do_set_base(crtc, fb, x, y, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tilcdc_disable(struct drm_crtc *crtc)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
tilcdc_prepare(struct drm_crtc *crtc)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
tilcdc_commit(struct drm_crtc *crtc)
|
||||
{
|
||||
struct tilcdc_crtc *mixer_crtc = to_tilcdc_crtc(crtc);
|
||||
struct tilcdc_softc * const sc = mixer_crtc->sc;
|
||||
uint32_t val;
|
||||
|
||||
WR4(sc, LCD_CLKC_ENABLE, CLKC_ENABLE_DMA | CLKC_ENABLE_CORE);
|
||||
WR4(sc, LCD_CLKC_RESET, CLKC_RESET_MAIN);
|
||||
delay(100);
|
||||
WR4(sc, LCD_CLKC_RESET, 0);
|
||||
|
||||
val = RD4(sc, LCD_RASTER_CTRL);
|
||||
WR4(sc, LCD_RASTER_CTRL, val | RASTER_CTRL_LCDEN);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = {
|
||||
.dpms = tilcdc_dpms,
|
||||
.mode_fixup = tilcdc_mode_fixup,
|
||||
.mode_set = tilcdc_mode_set,
|
||||
.mode_set_base = tilcdc_mode_set_base,
|
||||
.mode_set_base_atomic = tilcdc_mode_set_base_atomic,
|
||||
.disable = tilcdc_disable,
|
||||
.prepare = tilcdc_prepare,
|
||||
.commit = tilcdc_commit,
|
||||
};
|
||||
|
||||
static void
|
||||
tilcdc_encoder_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct drm_encoder_funcs tilcdc_encoder_funcs = {
|
||||
.destroy = tilcdc_encoder_destroy,
|
||||
};
|
||||
|
||||
static void
|
||||
tilcdc_encoder_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
}
|
||||
|
||||
static bool
|
||||
tilcdc_encoder_mode_fixup(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
tilcdc_encoder_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
tilcdc_encoder_prepare(struct drm_encoder *encoder)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
tilcdc_encoder_commit(struct drm_encoder *encoder)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs tilcdc_encoder_helper_funcs = {
|
||||
.dpms = tilcdc_encoder_dpms,
|
||||
.mode_fixup = tilcdc_encoder_mode_fixup,
|
||||
.prepare = tilcdc_encoder_prepare,
|
||||
.commit = tilcdc_encoder_commit,
|
||||
.mode_set = tilcdc_encoder_mode_set,
|
||||
};
|
||||
|
||||
static int
|
||||
tilcdc_ep_activate(device_t dev, struct fdt_endpoint *ep, bool activate)
|
||||
{
|
||||
struct tilcdc_softc * const sc = device_private(dev);
|
||||
struct drm_device *ddev = sc->sc_ddev;
|
||||
|
||||
if (!activate)
|
||||
return EINVAL;
|
||||
|
||||
sc->sc_crtc.sc = sc;
|
||||
|
||||
WR4(sc, LCD_SYSCONFIG, SYSCONFIG_STANDBY_SMART | SYSCONFIG_IDLE_SMART);
|
||||
|
||||
drm_crtc_init(ddev, &sc->sc_crtc.base, &tilcdc_crtc_funcs);
|
||||
drm_crtc_helper_add(&sc->sc_crtc.base, &tilcdc_crtc_helper_funcs);
|
||||
|
||||
sc->sc_encoder.sc = sc;
|
||||
sc->sc_encoder.base.possible_crtcs = 1 << drm_crtc_index(&sc->sc_crtc.base);
|
||||
|
||||
drm_encoder_init(ddev, &sc->sc_encoder.base, &tilcdc_encoder_funcs,
|
||||
DRM_MODE_ENCODER_TMDS);
|
||||
drm_encoder_helper_add(&sc->sc_encoder.base, &tilcdc_encoder_helper_funcs);
|
||||
|
||||
return fdt_endpoint_activate(ep, activate);
|
||||
}
|
||||
|
||||
static void *
|
||||
tilcdc_ep_get_data(device_t dev, struct fdt_endpoint *ep)
|
||||
{
|
||||
struct tilcdc_softc * const sc = device_private(dev);
|
||||
|
||||
return &sc->sc_encoder.base;
|
||||
}
|
||||
|
||||
static int
|
||||
tilcdc_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
|
||||
tilcdc_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct tilcdc_softc * const sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
struct drm_driver * const driver = &tilcdc_driver;
|
||||
prop_dictionary_t dict = device_properties(self);
|
||||
bool is_disabled;
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
int error;
|
||||
|
||||
if (prop_dictionary_get_bool(dict, "disabled", &is_disabled) && is_disabled) {
|
||||
aprint_normal(": TI LCDC (disabled)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_phandle = faa->faa_phandle;
|
||||
sc->sc_dmat = faa->faa_dmat;
|
||||
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;
|
||||
}
|
||||
sc->sc_clk = ti_prcm_get_hwmod(phandle, 0);
|
||||
if (sc->sc_clk == NULL || clk_enable(sc->sc_clk) != 0) {
|
||||
aprint_error(": couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": TI LCDC\n");
|
||||
|
||||
sc->sc_ports.dp_ep_activate = tilcdc_ep_activate;
|
||||
sc->sc_ports.dp_ep_get_data = tilcdc_ep_get_data;
|
||||
fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_ENCODER);
|
||||
|
||||
sc->sc_ddev = drm_dev_alloc(driver, sc->sc_dev);
|
||||
if (sc->sc_ddev == NULL) {
|
||||
aprint_error_dev(self, "couldn't allocate DRM device\n");
|
||||
return;
|
||||
}
|
||||
sc->sc_ddev->dev_private = sc;
|
||||
sc->sc_ddev->bst = sc->sc_bst;
|
||||
sc->sc_ddev->bus_dmat = sc->sc_dmat;
|
||||
sc->sc_ddev->dmat = sc->sc_ddev->bus_dmat;
|
||||
sc->sc_ddev->dmat_subregion_p = false;
|
||||
|
||||
error = -drm_dev_register(sc->sc_ddev, 0);
|
||||
if (error) {
|
||||
drm_dev_unref(sc->sc_ddev);
|
||||
aprint_error_dev(self, "couldn't register DRM device: %d\n",
|
||||
error);
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_normal_dev(self, "initialized %s %d.%d.%d %s on minor %d\n",
|
||||
driver->name, driver->major, driver->minor, driver->patchlevel,
|
||||
driver->date, sc->sc_ddev->primary->index);
|
||||
}
|
||||
|
||||
static int
|
||||
tilcdc_set_busid(struct drm_device *ddev, struct drm_master *master)
|
||||
{
|
||||
struct tilcdc_softc * const sc = tilcdc_private(ddev);
|
||||
char id[32];
|
||||
|
||||
snprintf(id, sizeof(id), "platform:tilcdc:%u", device_unit(sc->sc_dev));
|
||||
|
||||
master->unique = kzalloc(strlen(id) + 1, GFP_KERNEL);
|
||||
if (master->unique == NULL)
|
||||
return -ENOMEM;
|
||||
strcpy(master->unique, id);
|
||||
master->unique_len = strlen(master->unique);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tilcdc_fb_create_handle(struct drm_framebuffer *fb,
|
||||
struct drm_file *file, unsigned int *handle)
|
||||
{
|
||||
struct tilcdc_framebuffer *sfb = to_tilcdc_framebuffer(fb);
|
||||
|
||||
return drm_gem_handle_create(file, &sfb->obj->base, handle);
|
||||
}
|
||||
|
||||
static void
|
||||
tilcdc_fb_destroy(struct drm_framebuffer *fb)
|
||||
{
|
||||
struct tilcdc_framebuffer *sfb = to_tilcdc_framebuffer(fb);
|
||||
|
||||
drm_framebuffer_cleanup(fb);
|
||||
drm_gem_object_unreference_unlocked(&sfb->obj->base);
|
||||
kmem_free(sfb, sizeof(*sfb));
|
||||
}
|
||||
|
||||
static const struct drm_framebuffer_funcs tilcdc_framebuffer_funcs = {
|
||||
.create_handle = tilcdc_fb_create_handle,
|
||||
.destroy = tilcdc_fb_destroy,
|
||||
};
|
||||
|
||||
static struct drm_framebuffer *
|
||||
tilcdc_fb_create(struct drm_device *ddev, struct drm_file *file,
|
||||
struct drm_mode_fb_cmd2 *cmd)
|
||||
{
|
||||
struct tilcdc_framebuffer *fb;
|
||||
struct drm_gem_object *gem_obj;
|
||||
int error;
|
||||
|
||||
if (cmd->flags)
|
||||
return NULL;
|
||||
|
||||
gem_obj = drm_gem_object_lookup(ddev, file, cmd->handles[0]);
|
||||
if (gem_obj == NULL)
|
||||
return NULL;
|
||||
|
||||
fb = kmem_zalloc(sizeof(*fb), KM_SLEEP);
|
||||
fb->obj = to_drm_gem_cma_obj(gem_obj);
|
||||
fb->base.pitches[0] = cmd->pitches[0];
|
||||
fb->base.pitches[1] = cmd->pitches[1];
|
||||
fb->base.pitches[2] = cmd->pitches[2];
|
||||
fb->base.offsets[0] = cmd->offsets[0];
|
||||
fb->base.offsets[1] = cmd->offsets[2];
|
||||
fb->base.offsets[2] = cmd->offsets[1];
|
||||
fb->base.width = cmd->width;
|
||||
fb->base.height = cmd->height;
|
||||
fb->base.pixel_format = cmd->pixel_format;
|
||||
fb->base.bits_per_pixel = drm_format_plane_cpp(fb->base.pixel_format, 0) * 8;
|
||||
|
||||
switch (fb->base.pixel_format) {
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
case DRM_FORMAT_XBGR8888:
|
||||
fb->base.depth = 32;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
error = drm_framebuffer_init(ddev, &fb->base, &tilcdc_framebuffer_funcs);
|
||||
if (error != 0)
|
||||
goto dealloc;
|
||||
|
||||
return &fb->base;
|
||||
|
||||
dealloc:
|
||||
drm_framebuffer_cleanup(&fb->base);
|
||||
kmem_free(fb, sizeof(*fb));
|
||||
drm_gem_object_unreference_unlocked(gem_obj);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct drm_mode_config_funcs tilcdc_mode_config_funcs = {
|
||||
.fb_create = tilcdc_fb_create,
|
||||
};
|
||||
|
||||
static int
|
||||
tilcdc_fb_probe(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes)
|
||||
{
|
||||
struct tilcdc_softc * const sc = tilcdc_private(helper->dev);
|
||||
struct drm_device *ddev = helper->dev;
|
||||
struct tilcdc_framebuffer *sfb = to_tilcdc_framebuffer(helper->fb);
|
||||
struct drm_framebuffer *fb = helper->fb;
|
||||
struct tilcdcfb_attach_args tfa;
|
||||
const char *br_wiring;
|
||||
uint32_t pixel_format;
|
||||
int error;
|
||||
|
||||
const u_int width = sizes->surface_width;
|
||||
const u_int height = sizes->surface_height;
|
||||
const u_int pitch = width * (32 / 8);
|
||||
|
||||
br_wiring = fdtbus_get_string(sc->sc_phandle, "blue-and-red-wiring");
|
||||
if (br_wiring && strcmp(br_wiring, "straight") == 0) {
|
||||
pixel_format = DRM_FORMAT_XBGR8888;
|
||||
} else {
|
||||
pixel_format = DRM_FORMAT_XRGB8888;
|
||||
}
|
||||
|
||||
const size_t size = roundup(height * pitch, PAGE_SIZE);
|
||||
|
||||
sfb->obj = drm_gem_cma_create(ddev, size);
|
||||
if (sfb->obj == NULL) {
|
||||
DRM_ERROR("failed to allocate memory for framebuffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fb->pitches[0] = pitch;
|
||||
fb->offsets[0] = 0;
|
||||
fb->width = width;
|
||||
fb->height = height;
|
||||
fb->pixel_format = pixel_format;
|
||||
drm_fb_get_bpp_depth(fb->pixel_format, &fb->depth, &fb->bits_per_pixel);
|
||||
|
||||
error = drm_framebuffer_init(ddev, fb, &tilcdc_framebuffer_funcs);
|
||||
if (error != 0) {
|
||||
DRM_ERROR("failed to initialize framebuffer\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
memset(&tfa, 0, sizeof(tfa));
|
||||
tfa.tfa_drm_dev = ddev;
|
||||
tfa.tfa_fb_helper = helper;
|
||||
tfa.tfa_fb_sizes = *sizes;
|
||||
tfa.tfa_fb_bst = sc->sc_bst;
|
||||
tfa.tfa_fb_dmat = sc->sc_dmat;
|
||||
tfa.tfa_fb_linebytes = helper->fb->pitches[0];
|
||||
|
||||
helper->fbdev = config_found_ia(ddev->dev, "tilcdcfbbus", &tfa, NULL);
|
||||
if (helper->fbdev == NULL) {
|
||||
DRM_ERROR("unable to attach framebuffer\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_fb_helper_funcs tilcdc_fb_helper_funcs = {
|
||||
.fb_probe = tilcdc_fb_probe,
|
||||
};
|
||||
|
||||
static int
|
||||
tilcdc_load(struct drm_device *ddev, unsigned long flags)
|
||||
{
|
||||
struct tilcdc_softc * const sc = tilcdc_private(ddev);
|
||||
struct tilcdc_fbdev *fbdev;
|
||||
struct fdt_endpoint *ep;
|
||||
int error;
|
||||
|
||||
drm_mode_config_init(ddev);
|
||||
ddev->mode_config.min_width = 0;
|
||||
ddev->mode_config.min_height = 0;
|
||||
ddev->mode_config.max_width = 2048;
|
||||
ddev->mode_config.max_height = 2048;
|
||||
ddev->mode_config.funcs = &tilcdc_mode_config_funcs;
|
||||
|
||||
ep = fdt_endpoint_get_from_index(&sc->sc_ports, TILCDC_PORT_OUTPUT, 0);
|
||||
if (ep == NULL) {
|
||||
aprint_error_dev(sc->sc_dev, "couldn't find endpoint\n");
|
||||
return ENXIO;
|
||||
}
|
||||
error = fdt_endpoint_activate_direct(ep, true);
|
||||
if (error != 0) {
|
||||
aprint_error_dev(sc->sc_dev, "couldn't activate endpoint: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
fbdev = kmem_zalloc(sizeof(*fbdev), KM_SLEEP);
|
||||
|
||||
drm_fb_helper_prepare(ddev, &fbdev->helper, &tilcdc_fb_helper_funcs);
|
||||
|
||||
error = drm_fb_helper_init(ddev, &fbdev->helper, 1, 1);
|
||||
if (error)
|
||||
goto drmerr;
|
||||
|
||||
fbdev->helper.fb = kmem_zalloc(sizeof(struct tilcdc_framebuffer), KM_SLEEP);
|
||||
|
||||
drm_fb_helper_single_add_all_connectors(&fbdev->helper);
|
||||
|
||||
drm_helper_disable_unused_functions(ddev);
|
||||
|
||||
drm_fb_helper_initial_config(&fbdev->helper, 32);
|
||||
|
||||
return 0;
|
||||
|
||||
drmerr:
|
||||
drm_mode_config_cleanup(ddev);
|
||||
kmem_free(fbdev, sizeof(*fbdev));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
tilcdc_unload(struct drm_device *ddev)
|
||||
{
|
||||
drm_mode_config_cleanup(ddev);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/* $NetBSD: ti_lcdc.h,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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.
|
||||
*/
|
||||
|
||||
#ifndef _ARM_TI_TI_LCDC_H
|
||||
#define _ARM_TI_TI_LCDC_H
|
||||
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_gem_cma_helper.h>
|
||||
|
||||
#define DRIVER_AUTHOR "NetBSD"
|
||||
|
||||
#define DRIVER_NAME "tilcdc"
|
||||
#define DRIVER_DESC "TI LCDC"
|
||||
#define DRIVER_DATE "20191103"
|
||||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 0
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
struct tilcdc_softc;
|
||||
struct tilcdc_framebuffer;
|
||||
|
||||
struct tilcdc_vblank {
|
||||
void *priv;
|
||||
void (*enable_vblank)(void *);
|
||||
void (*disable_vblank)(void *);
|
||||
uint32_t (*get_vblank_counter)(void *);
|
||||
};
|
||||
|
||||
struct tilcdc_crtc {
|
||||
struct drm_crtc base;
|
||||
struct tilcdc_softc *sc;
|
||||
};
|
||||
|
||||
struct tilcdc_encoder {
|
||||
struct drm_encoder base;
|
||||
struct tilcdc_softc *sc;
|
||||
};
|
||||
|
||||
struct tilcdc_softc {
|
||||
device_t sc_dev;
|
||||
struct drm_device *sc_ddev;
|
||||
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
bus_dma_tag_t sc_dmat;
|
||||
|
||||
struct clk *sc_clk;
|
||||
int sc_phandle;
|
||||
|
||||
struct tilcdc_crtc sc_crtc;
|
||||
struct tilcdc_encoder sc_encoder;
|
||||
struct tilcdc_vblank sc_vbl;
|
||||
|
||||
struct fdt_device_ports sc_ports;
|
||||
};
|
||||
|
||||
struct tilcdc_framebuffer {
|
||||
struct drm_framebuffer base;
|
||||
struct drm_gem_cma_object *obj;
|
||||
};
|
||||
|
||||
struct tilcdc_fbdev {
|
||||
struct drm_fb_helper helper;
|
||||
};
|
||||
|
||||
struct tilcdcfb_attach_args {
|
||||
struct drm_device *tfa_drm_dev;
|
||||
struct drm_fb_helper *tfa_fb_helper;
|
||||
struct drm_fb_helper_surface_size tfa_fb_sizes;
|
||||
bus_space_tag_t tfa_fb_bst;
|
||||
bus_dma_tag_t tfa_fb_dmat;
|
||||
uint32_t tfa_fb_linebytes;
|
||||
};
|
||||
|
||||
#define tilcdc_private(ddev) (ddev)->dev_private
|
||||
#define to_tilcdc_framebuffer(x) container_of(x, struct tilcdc_framebuffer, base)
|
||||
#define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
|
||||
|
||||
#define RD4(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
|
||||
#define WR4(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
|
||||
|
||||
#endif /* _ARM_TI_TI_LCDC_H */
|
|
@ -0,0 +1,136 @@
|
|||
/* $NetBSD: ti_lcdcreg.h,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
/*-
|
||||
* Copyright 2013 Oleksandr Tymoshenko <gonzo@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.
|
||||
*/
|
||||
|
||||
#define LCD_PID 0x00
|
||||
#define LCD_CTRL 0x04
|
||||
#define CTRL_DIV_MASK 0xff
|
||||
#define CTRL_DIV_SHIFT 8
|
||||
#define CTRL_AUTO_UFLOW_RESTART (1 << 1)
|
||||
#define CTRL_RASTER_MODE 1
|
||||
#define CTRL_LIDD_MODE 0
|
||||
#define LCD_LIDD_CTRL 0x0C
|
||||
#define LCD_LIDD_CS0_CONF 0x10
|
||||
#define LCD_LIDD_CS0_ADDR 0x14
|
||||
#define LCD_LIDD_CS0_DATA 0x18
|
||||
#define LCD_LIDD_CS1_CONF 0x1C
|
||||
#define LCD_LIDD_CS1_ADDR 0x20
|
||||
#define LCD_LIDD_CS1_DATA 0x24
|
||||
#define LCD_RASTER_CTRL 0x28
|
||||
#define RASTER_CTRL_TFT24_UNPACKED (1 << 26)
|
||||
#define RASTER_CTRL_TFT24 (1 << 25)
|
||||
#define RASTER_CTRL_STN565 (1 << 24)
|
||||
#define RASTER_CTRL_TFTMAP (1 << 23)
|
||||
#define RASTER_CTRL_NIBMODE (1 << 22)
|
||||
#define RASTER_CTRL_PALMODE_PALETTE_AND_DATA (0 << 20)
|
||||
#define RASTER_CTRL_PALMODE_PALETTE_ONLY (1 << 20)
|
||||
#define RASTER_CTRL_PALMODE_DATA_ONLY (2 << 20)
|
||||
#define RASTER_CTRL_REQDLY(v) ((v) << 12)
|
||||
#define RASTER_CTRL_MONO8B (1 << 9)
|
||||
#define RASTER_CTRL_RDORDER (1 << 8)
|
||||
#define RASTER_CTRL_LCDTFT (1 << 7)
|
||||
#define RASTER_CTRL_LCDBW (1 << 1)
|
||||
#define RASTER_CTRL_LCDEN (1 << 0)
|
||||
#define LCD_RASTER_TIMING_0 0x2C
|
||||
#define RASTER_TIMING_0_HBP(v) ((((v) - 1) & 0xff) << 24)
|
||||
#define RASTER_TIMING_0_HFP(v) ((((v) - 1) & 0xff) << 16)
|
||||
#define RASTER_TIMING_0_HSW(v) ((((v) - 1) & 0x3f) << 10)
|
||||
#define RASTER_TIMING_0_PPL(w) \
|
||||
(((((w) - 1) >> 7) & 0x8) | ((((w) - 1) >> 0) & 0x3f0))
|
||||
#define LCD_RASTER_TIMING_1 0x30
|
||||
#define RASTER_TIMING_1_VBP(v) (((v) & 0xff) << 24)
|
||||
#define RASTER_TIMING_1_VFP(v) (((v) & 0xff) << 16)
|
||||
#define RASTER_TIMING_1_VSW(v) ((((v) - 1) & 0x3f) << 10)
|
||||
#define RASTER_TIMING_1_LPP(h) ((((h) - 1) & 0x3ff) << 0)
|
||||
#define LCD_RASTER_TIMING_2 0x34
|
||||
#define RASTER_TIMING_2_HSW(v) (((((v) - 1) >> 6) & 0xf) << 27)
|
||||
#define RASTER_TIMING_2_LPP(h) (((h) & 0x400) ? (1 << 26) : 0)
|
||||
#define RASTER_TIMING_2_PHSVS (1 << 25)
|
||||
#define RASTER_TIMING_2_PHSVS_RISE (1 << 24)
|
||||
#define RASTER_TIMING_2_PHSVS_FALL (0 << 24)
|
||||
#define RASTER_TIMING_2_IOE (1 << 23)
|
||||
#define RASTER_TIMING_2_IPC (1 << 22)
|
||||
#define RASTER_TIMING_2_IHS (1 << 21)
|
||||
#define RASTER_TIMING_2_IVS (1 << 20)
|
||||
#define RASTER_TIMING_2_ACBI(x) ((x) << 16)
|
||||
#define RASTER_TIMING_2_ACB(x) ((x) << 8)
|
||||
#define RASTER_TIMING_2_HBP(v) ((((v) - 1) >> 4) & 0x30)
|
||||
#define RASTER_TIMING_2_HFP(v) ((((v) - 1) >> 8) & 0x3)
|
||||
#define LCD_RASTER_SUBPANEL 0x38
|
||||
#define LCD_RASTER_SUBPANEL2 0x3C
|
||||
#define LCD_LCDDMA_CTRL 0x40
|
||||
#define LCDDMA_CTRL_DMA_MASTER_PRIO_SHIFT 16
|
||||
#define LCDDMA_CTRL_TH_FIFO_RDY_SHIFT 8
|
||||
#define LCDDMA_CTRL_BURST_SIZE_SHIFT 4
|
||||
#define LCDDMA_CTRL_BYTES_SWAP (1 << 3)
|
||||
#define LCDDMA_CTRL_BE (1 << 1)
|
||||
#define LCDDMA_CTRL_FB0_FB1 (1 << 0)
|
||||
#define LCDDMA_CTRL_FB0_ONLY (0 << 0)
|
||||
#define LCD_LCDDMA_FB0_BASE 0x44
|
||||
#define LCD_LCDDMA_FB0_CEILING 0x48
|
||||
#define LCD_LCDDMA_FB1_BASE 0x4C
|
||||
#define LCD_LCDDMA_FB1_CEILING 0x50
|
||||
#define LCD_SYSCONFIG 0x54
|
||||
#define SYSCONFIG_STANDBY_FORCE (0 << 4)
|
||||
#define SYSCONFIG_STANDBY_NONE (1 << 4)
|
||||
#define SYSCONFIG_STANDBY_SMART (2 << 4)
|
||||
#define SYSCONFIG_IDLE_FORCE (0 << 2)
|
||||
#define SYSCONFIG_IDLE_NONE (1 << 2)
|
||||
#define SYSCONFIG_IDLE_SMART (2 << 2)
|
||||
#define LCD_IRQSTATUS_RAW 0x58
|
||||
#define LCD_IRQSTATUS 0x5C
|
||||
#define LCD_IRQENABLE_SET 0x60
|
||||
#define LCD_IRQENABLE_CLEAR 0x64
|
||||
#define IRQ_EOF1 (1 << 9)
|
||||
#define IRQ_EOF0 (1 << 8)
|
||||
#define IRQ_PL (1 << 6)
|
||||
#define IRQ_FUF (1 << 5)
|
||||
#define IRQ_ACB (1 << 3)
|
||||
#define IRQ_SYNC_LOST (1 << 2)
|
||||
#define IRQ_RASTER_DONE (1 << 1)
|
||||
#define IRQ_FRAME_DONE (1 << 0)
|
||||
#define LCD_CLKC_ENABLE 0x6C
|
||||
#define CLKC_ENABLE_DMA (1 << 2)
|
||||
#define CLKC_ENABLE_LIDD (1 << 1)
|
||||
#define CLKC_ENABLE_CORE (1 << 0)
|
||||
#define LCD_CLKC_RESET 0x70
|
||||
#define CLKC_RESET_MAIN (1 << 3)
|
||||
#define CLKC_RESET_DMA (1 << 2)
|
||||
#define CLKC_RESET_LIDD (1 << 1)
|
||||
#define CLKC_RESET_CORE (1 << 0)
|
||||
|
||||
/* 16-Entry Palette/Buffer Format */
|
||||
#define PALETTE_BPP_1 (0 << 12)
|
||||
#define PALETTE_BPP_2 (1 << 12)
|
||||
#define PALETTE_BPP_4 (2 << 12)
|
||||
#define PALETTE_BPP_8 (3 << 12)
|
||||
#define PALETTE_BPP_XX (4 << 12)
|
||||
#define PALETTE_MONO(v) ((v) & 0xf)
|
||||
#define PALETTE_RED(r) (((r) & 0xf) << 8)
|
||||
#define PALETTE_GREEN(g) (((g) & 0xf) << 4)
|
||||
#define PALETTE_BLUE(b) (((b) & 0xf) << 0)
|
||||
#define PALETTE_COLOR(r, g, b) \
|
||||
(PALETTE_RED(r) | PALETTE_GREEN(g) | PALETTE_BLUE(b))
|
|
@ -0,0 +1,237 @@
|
|||
/* $NetBSD: ti_motg.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Manuel Bouyer. 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: ti_motg.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
#include <arm/ti/ti_otgreg.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/motgreg.h>
|
||||
#include <dev/usb/motgvar.h>
|
||||
#include <dev/usb/usbhist.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
#ifndef MOTG_DEBUG
|
||||
#define motgdebug 0
|
||||
#else
|
||||
extern int motgdebug;
|
||||
#endif /* MOTG_DEBUG */
|
||||
#endif /* USB_DEBUG */
|
||||
|
||||
#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(motgdebug,1,FMT,A,B,C,D)
|
||||
#define MOTGHIST_FUNC() USBHIST_FUNC()
|
||||
#define MOTGHIST_CALLED(name) USBHIST_CALLED(motgdebug)
|
||||
|
||||
static const char * compatible [] = {
|
||||
"ti,musb-am33xx",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* motg device attachement and driver,
|
||||
* for the per-port part of the controller: TI-specific part, phy and
|
||||
* MI Mentor OTG.
|
||||
*/
|
||||
|
||||
struct ti_motg_softc {
|
||||
struct motg_softc sc_motg;
|
||||
bus_space_tag_t sc_ctrliot;
|
||||
bus_space_handle_t sc_ctrlioh;
|
||||
void * sc_ctrlih;
|
||||
int sc_ctrlport;
|
||||
};
|
||||
|
||||
static int ti_motg_match(device_t, cfdata_t, void *);
|
||||
static void ti_motg_attach(device_t, device_t, void *);
|
||||
static int ti_motg_intr(void *);
|
||||
static void ti_motg_poll(void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_motg, sizeof(struct ti_motg_softc),
|
||||
ti_motg_match, ti_motg_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
ti_motg_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_motg_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_motg_softc *sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
char intrstr[128];
|
||||
bus_addr_t addr[2];
|
||||
bus_size_t size[2];
|
||||
uint32_t val;
|
||||
|
||||
MOTGHIST_FUNC(); MOTGHIST_CALLED();
|
||||
|
||||
if (fdtbus_get_reg_byname(phandle, "mc", &addr[0], &size[0]) != 0 ||
|
||||
fdtbus_get_reg_byname(phandle, "control", &addr[1], &size[1])) {
|
||||
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;
|
||||
}
|
||||
|
||||
sc->sc_motg.sc_dev = self;
|
||||
sc->sc_ctrliot = faa->faa_bst;
|
||||
if (bus_space_map(sc->sc_ctrliot, addr[1], size[1], 0, &sc->sc_ctrlioh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
sc->sc_ctrlih = fdtbus_intr_establish(phandle, 0, IPL_USB, 0,
|
||||
ti_motg_intr, sc);
|
||||
sc->sc_motg.sc_bus.ub_dmatag = faa->faa_dmat;
|
||||
|
||||
val = TIOTG_USBC_READ4(sc, USBCTRL_REV);
|
||||
aprint_normal(": 0x%x version v%d.%d.%d", val,
|
||||
(val >> 8) & 7, (val >> 6) & 3, val & 63);
|
||||
|
||||
/* XXX configure mode */
|
||||
#if 0
|
||||
if (sc->sc_ctrlport == 0)
|
||||
sc->sc_motg.sc_mode = MOTG_MODE_DEVICE;
|
||||
else
|
||||
sc->sc_motg.sc_mode = MOTG_MODE_HOST;
|
||||
#else
|
||||
/* XXXXX
|
||||
* Both ports always the host mode only.
|
||||
* And motg(4) doesn't supports device and OTG modes.
|
||||
*/
|
||||
sc->sc_motg.sc_mode = MOTG_MODE_HOST;
|
||||
#endif
|
||||
if (sc->sc_motg.sc_mode == MOTG_MODE_HOST) {
|
||||
val = TIOTG_USBC_READ4(sc, USBCTRL_MODE);
|
||||
val |= USBCTRL_MODE_IDDIGMUX;
|
||||
val &= ~USBCTRL_MODE_IDDIG;
|
||||
TIOTG_USBC_WRITE4(sc, USBCTRL_MODE, val);
|
||||
TIOTG_USBC_WRITE4(sc, USBCTRL_UTMI, USBCTRL_UTMI_FSDATAEXT);
|
||||
} else {
|
||||
val = TIOTG_USBC_READ4(sc, USBCTRL_MODE);
|
||||
val |= USBCTRL_MODE_IDDIGMUX;
|
||||
val |= USBCTRL_MODE_IDDIG;
|
||||
TIOTG_USBC_WRITE4(sc, USBCTRL_MODE, val);
|
||||
}
|
||||
|
||||
aprint_normal("\n");
|
||||
aprint_naive("\n");
|
||||
|
||||
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
|
||||
|
||||
sc->sc_motg.sc_iot = faa->faa_bst;
|
||||
if (bus_space_map(sc->sc_motg.sc_iot, addr[0], size[0], 0,
|
||||
&sc->sc_motg.sc_ioh) != 0) {
|
||||
aprint_error_dev(self, "couldn't map mc registers\n");
|
||||
return;
|
||||
}
|
||||
sc->sc_motg.sc_size = size[0];
|
||||
sc->sc_motg.sc_intr_poll = ti_motg_poll;
|
||||
sc->sc_motg.sc_intr_poll_arg = sc;
|
||||
delay(10);
|
||||
motg_init(&sc->sc_motg);
|
||||
/* enable interrupts */
|
||||
TIOTG_USBC_WRITE4(sc, USBCTRL_INTEN_SET0, 0xffffffff);
|
||||
TIOTG_USBC_WRITE4(sc, USBCTRL_INTEN_SET1,
|
||||
USBCTRL_INTEN_USB_ALL & ~USBCTRL_INTEN_USB_SOF);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_motg_intr(void *v)
|
||||
{
|
||||
struct ti_motg_softc *sc = v;
|
||||
uint32_t stat, stat0, stat1;
|
||||
int rv = 0;
|
||||
int i;
|
||||
|
||||
MOTGHIST_FUNC(); MOTGHIST_CALLED();
|
||||
|
||||
mutex_spin_enter(&sc->sc_motg.sc_intr_lock);
|
||||
stat = TIOTG_USBC_READ4(sc, USBCTRL_STAT);
|
||||
stat0 = TIOTG_USBC_READ4(sc, USBCTRL_IRQ_STAT0);
|
||||
stat1 = TIOTG_USBC_READ4(sc, USBCTRL_IRQ_STAT1);
|
||||
DPRINTF("USB %jd 0x%jx 0x%jx stat %jd",
|
||||
sc->sc_ctrlport, stat0, stat1, stat);
|
||||
/* try to deal with vbus errors */
|
||||
if (stat1 & MUSB2_MASK_IVBUSERR ) {
|
||||
stat1 &= ~MUSB2_MASK_IVBUSERR;
|
||||
for (i = 0; i < 1000; i++) {
|
||||
TIOTG_USBC_WRITE4(sc, USBCTRL_IRQ_STAT1,
|
||||
MUSB2_MASK_IVBUSERR);
|
||||
motg_intr_vbus(&sc->sc_motg, stat & 0x1);
|
||||
delay(1000);
|
||||
stat = TIOTG_USBC_READ4(sc, USBCTRL_STAT);
|
||||
if (stat & 0x1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stat0) {
|
||||
TIOTG_USBC_WRITE4(sc, USBCTRL_IRQ_STAT0, stat0);
|
||||
}
|
||||
if (stat1) {
|
||||
TIOTG_USBC_WRITE4(sc, USBCTRL_IRQ_STAT1, stat1);
|
||||
}
|
||||
if ((stat & 0x1) == 0) {
|
||||
mutex_spin_exit(&sc->sc_motg.sc_intr_lock);
|
||||
aprint_error_dev(sc->sc_motg.sc_dev, ": vbus error\n");
|
||||
return 1;
|
||||
}
|
||||
if (stat0 != 0 || stat1 != 0) {
|
||||
rv = motg_intr(&sc->sc_motg, ((stat0 >> 16) & 0xffff),
|
||||
stat0 & 0xffff, stat1 & 0xff);
|
||||
}
|
||||
mutex_spin_exit(&sc->sc_motg.sc_intr_lock);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_motg_poll(void *v)
|
||||
{
|
||||
ti_motg_intr(v);
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
/* $NetBSD: ti_mux_clock.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: ti_mux_clock.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/clk/clk_backend.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
static int ti_mux_clock_match(device_t, cfdata_t, void *);
|
||||
static void ti_mux_clock_attach(device_t, device_t, void *);
|
||||
|
||||
static struct clk *ti_mux_clock_decode(device_t, int, const void *, size_t);
|
||||
|
||||
static const struct fdtbus_clock_controller_func ti_mux_clock_fdt_funcs = {
|
||||
.decode = ti_mux_clock_decode
|
||||
};
|
||||
|
||||
static struct clk *ti_mux_clock_get(void *, const char *);
|
||||
static void ti_mux_clock_put(void *, struct clk *);
|
||||
static u_int ti_mux_clock_get_rate(void *, struct clk *);
|
||||
static struct clk *ti_mux_clock_get_parent(void *, struct clk *);
|
||||
static int ti_mux_clock_set_parent(void *, struct clk *, struct clk *);
|
||||
|
||||
static const struct clk_funcs ti_mux_clock_clk_funcs = {
|
||||
.get = ti_mux_clock_get,
|
||||
.put = ti_mux_clock_put,
|
||||
.get_rate = ti_mux_clock_get_rate,
|
||||
.get_parent = ti_mux_clock_get_parent,
|
||||
.set_parent = ti_mux_clock_set_parent,
|
||||
};
|
||||
|
||||
struct ti_mux_clock_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 clk sc_clk;
|
||||
u_int sc_nparent;
|
||||
|
||||
uint32_t sc_mask;
|
||||
u_int sc_start_index;
|
||||
};
|
||||
|
||||
#define RD4(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
|
||||
#define WR4(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
|
||||
|
||||
CFATTACH_DECL_NEW(ti_mux_clock, sizeof(struct ti_mux_clock_softc),
|
||||
ti_mux_clock_match, ti_mux_clock_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
ti_mux_clock_match(device_t parent, cfdata_t cf, void *aux)
|
||||
{
|
||||
const char * const compatible[] = { "ti,mux-clock", NULL };
|
||||
const struct fdt_attach_args *faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_mux_clock_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_mux_clock_softc * const sc = device_private(self);
|
||||
const struct fdt_attach_args *faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
bus_addr_t addr, base_addr;
|
||||
u_int shift;
|
||||
|
||||
const int prcm_phandle = OF_parent(OF_parent(phandle));
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, NULL) != 0 ||
|
||||
fdtbus_get_reg(prcm_phandle, 0, &base_addr, NULL) != 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, base_addr + addr, 4, 0, &sc->sc_bsh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_nparent = fdtbus_clock_count(phandle, "clocks");
|
||||
sc->sc_start_index = of_hasprop(phandle, "ti,index-starts-at-one") ? 1 : 0;
|
||||
sc->sc_nparent += sc->sc_start_index;
|
||||
while (!powerof2(sc->sc_nparent))
|
||||
sc->sc_nparent++;
|
||||
|
||||
if (of_getprop_uint32(phandle, "ti,bit-shift", &shift) != 0)
|
||||
shift = 0;
|
||||
|
||||
sc->sc_mask = (sc->sc_nparent - 1) << shift;
|
||||
|
||||
sc->sc_clkdom.name = device_xname(self);
|
||||
sc->sc_clkdom.funcs = &ti_mux_clock_clk_funcs;
|
||||
sc->sc_clkdom.priv = sc;
|
||||
|
||||
sc->sc_clk.domain = &sc->sc_clkdom;
|
||||
sc->sc_clk.name = kmem_asprintf("%s", faa->faa_name);
|
||||
clk_attach(&sc->sc_clk);
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": TI mux clock (%s)\n", sc->sc_clk.name);
|
||||
|
||||
fdtbus_register_clock_controller(self, phandle, &ti_mux_clock_fdt_funcs);
|
||||
}
|
||||
|
||||
static struct clk *
|
||||
ti_mux_clock_decode(device_t dev, int cc_phandle, const void *data,
|
||||
size_t len)
|
||||
{
|
||||
struct ti_mux_clock_softc * const sc = device_private(dev);
|
||||
|
||||
return &sc->sc_clk;
|
||||
}
|
||||
|
||||
static struct clk *
|
||||
ti_mux_clock_get(void *priv, const char *name)
|
||||
{
|
||||
struct ti_mux_clock_softc * const sc = priv;
|
||||
|
||||
return &sc->sc_clk;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_mux_clock_put(void *priv, struct clk *clk)
|
||||
{
|
||||
}
|
||||
|
||||
static u_int
|
||||
ti_mux_clock_get_rate(void *priv, struct clk *clk)
|
||||
{
|
||||
struct clk *clk_parent = clk_get_parent(clk);
|
||||
|
||||
if (clk_parent == NULL)
|
||||
return 0;
|
||||
|
||||
return clk_get_rate(clk_parent);
|
||||
}
|
||||
|
||||
static struct clk *
|
||||
ti_mux_clock_get_parent(void *priv, struct clk *clk)
|
||||
{
|
||||
struct ti_mux_clock_softc * const sc = priv;
|
||||
uint32_t val;
|
||||
u_int sel;
|
||||
|
||||
val = RD4(sc, 0);
|
||||
sel = __SHIFTOUT(val, sc->sc_mask);
|
||||
|
||||
return fdtbus_clock_get_index(sc->sc_phandle, sel - sc->sc_start_index);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_mux_clock_set_parent(void *priv, struct clk *clk, struct clk *parent_clk)
|
||||
{
|
||||
struct ti_mux_clock_softc * const sc = priv;
|
||||
uint32_t val;
|
||||
u_int sel;
|
||||
|
||||
for (sel = sc->sc_start_index; sel < sc->sc_nparent; sel++) {
|
||||
if (fdtbus_clock_get_index(sc->sc_phandle, sel - sc->sc_start_index) == parent_clk)
|
||||
break;
|
||||
}
|
||||
if (sel == sc->sc_nparent)
|
||||
return EINVAL;
|
||||
|
||||
val = RD4(sc, 0);
|
||||
val &= ~sc->sc_mask;
|
||||
val |= __SHIFTIN(sel, sc->sc_mask);
|
||||
WR4(sc, 0, val);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ti_omapintc.c,v 1.1 2017/10/26 01:16:32 jakllsch Exp $ */
|
||||
/* $NetBSD: ti_omapintc.c,v 1.1.10.1 2019/11/27 13:46:44 martin Exp $ */
|
||||
/*
|
||||
* Define the SDP2430 specific information and then include the generic OMAP
|
||||
* interrupt header.
|
||||
|
@ -29,11 +29,12 @@
|
|||
#define _INTR_PRIVATE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_omapintc.c,v 1.1 2017/10/26 01:16:32 jakllsch Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_omapintc.c,v 1.1.10.1 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/evcnt.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/kmem.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
|
@ -57,6 +58,12 @@ __KERNEL_RCSID(0, "$NetBSD: ti_omapintc.c,v 1.1 2017/10/26 01:16:32 jakllsch Exp
|
|||
|
||||
#define INTC_MAX_SOURCES 128
|
||||
|
||||
static const struct of_compat_data compat_data[] = {
|
||||
/* compatible number of banks */
|
||||
{ "ti,omap3-intc", 3 },
|
||||
{ "ti,am33xx-intc", 4 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
#define INTC_READ(sc, g, o) \
|
||||
bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, (g) * 0x20 + (o))
|
||||
|
@ -92,7 +99,8 @@ struct omap2icu_softc {
|
|||
bus_space_tag_t sc_memt;
|
||||
bus_space_handle_t sc_memh;
|
||||
struct pic_softc sc_pic;
|
||||
uint32_t sc_enabled_irqs[howmany(INTC_MAX_SOURCES, 32)];
|
||||
uint32_t *sc_enabled_irqs;
|
||||
u_int sc_nbank;
|
||||
};
|
||||
|
||||
static struct omap2icu_softc *intc_softc;
|
||||
|
@ -143,20 +151,16 @@ omap_irq_handler(void *frame)
|
|||
struct omap2icu_softc * const sc = intc_softc;
|
||||
const int oldipl = ci->ci_cpl;
|
||||
const uint32_t oldipl_mask = __BIT(oldipl);
|
||||
int ipl_mask = 0;
|
||||
int ipl_mask = 0, n;
|
||||
|
||||
ci->ci_data.cpu_nintr++;
|
||||
|
||||
if (sc->sc_enabled_irqs[0])
|
||||
ipl_mask |= find_pending_irqs(sc, 0);
|
||||
if (sc->sc_enabled_irqs[1])
|
||||
ipl_mask |= find_pending_irqs(sc, 1);
|
||||
if (sc->sc_enabled_irqs[2])
|
||||
ipl_mask |= find_pending_irqs(sc, 2);
|
||||
if (sc->sc_enabled_irqs[3])
|
||||
ipl_mask |= find_pending_irqs(sc, 3);
|
||||
for (n = 0; n < sc->sc_nbank; n++) {
|
||||
if (sc->sc_enabled_irqs[n])
|
||||
ipl_mask |= find_pending_irqs(sc, n);
|
||||
}
|
||||
|
||||
/* force INTC to recomputq IRQ */
|
||||
/* force INTC to recompute IRQ */
|
||||
INTC_WRITE(sc, 0, INTC_CONTROL, INTC_CONTROL_NEWIRQAGR);
|
||||
|
||||
/*
|
||||
|
@ -221,12 +225,7 @@ omap2icu_match(device_t parent, cfdata_t cf, void *aux)
|
|||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,am33xx-intc",
|
||||
NULL
|
||||
};
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
return of_match_compat_data(faa->faa_phandle, compat_data);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -237,7 +236,7 @@ omap2icu_attach(device_t parent, device_t self, void *aux)
|
|||
const int phandle = faa->faa_phandle;
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
int error;
|
||||
int error, n;
|
||||
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
|
@ -250,19 +249,21 @@ omap2icu_attach(device_t parent, device_t self, void *aux)
|
|||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
sc->sc_nbank = of_search_compatible(phandle, compat_data)->data;
|
||||
sc->sc_enabled_irqs =
|
||||
kmem_zalloc(sizeof(*sc->sc_enabled_irqs) * sc->sc_nbank, KM_SLEEP);
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal("\n");
|
||||
|
||||
INTC_WRITE(sc, 0, INTC_MIR_SET, 0xffffffff);
|
||||
INTC_WRITE(sc, 1, INTC_MIR_SET, 0xffffffff);
|
||||
INTC_WRITE(sc, 2, INTC_MIR_SET, 0xffffffff);
|
||||
for (n = 0; n < sc->sc_nbank; n++)
|
||||
INTC_WRITE(sc, n, INTC_MIR_SET, 0xffffffff);
|
||||
|
||||
sc->sc_dev = self;
|
||||
self->dv_private = sc;
|
||||
|
||||
sc->sc_pic.pic_ops = &omap2icu_picops;
|
||||
sc->sc_pic.pic_maxsources = INTC_MAX_SOURCES;
|
||||
sc->sc_pic.pic_maxsources = sc->sc_nbank * 32;
|
||||
snprintf(sc->sc_pic.pic_name, sizeof(sc->sc_pic.pic_name), "intc");
|
||||
pic_add(&sc->sc_pic, 0);
|
||||
error = fdtbus_register_interrupt_controller(self, phandle,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: ti_omaptimer.c,v 1.1 2017/10/26 01:16:32 jakllsch Exp $ */
|
||||
/* $NetBSD: ti_omaptimer.c,v 1.1.10.1 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_omaptimer.c,v 1.1 2017/10/26 01:16:32 jakllsch Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_omaptimer.c,v 1.1.10.1 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -15,10 +15,57 @@ __KERNEL_RCSID(0, "$NetBSD: ti_omaptimer.c,v 1.1 2017/10/26 01:16:32 jakllsch Ex
|
|||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,am335x-timer-1ms",
|
||||
"ti,am335x-timer",
|
||||
NULL
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
enum omaptimer_type {
|
||||
DM_TIMER_AM335X,
|
||||
DM_TIMER_OMAP3430,
|
||||
_DM_NTIMER
|
||||
};
|
||||
|
||||
enum {
|
||||
TIMER_TISR,
|
||||
TIMER_TIER,
|
||||
TIMER_TCLR,
|
||||
TIMER_TCRR,
|
||||
TIMER_TLDR,
|
||||
_TIMER_NREG
|
||||
};
|
||||
|
||||
/* TISR bits */
|
||||
#define OVF_IT_FLAG __BIT(1)
|
||||
|
||||
/* TIER bits */
|
||||
#define MAT_EN_FLAG __BIT(0)
|
||||
#define OVF_EN_FLAG __BIT(1)
|
||||
#define TCAR_EN_FLAG __BIT(2)
|
||||
|
||||
/* TCLR bits */
|
||||
#define TCLR_ST __BIT(0)
|
||||
#define TCLR_AR __BIT(1)
|
||||
|
||||
static uint8_t omaptimer_regmap[_DM_NTIMER][_TIMER_NREG] = {
|
||||
[DM_TIMER_AM335X] = {
|
||||
[TIMER_TISR] = 0x28,
|
||||
[TIMER_TIER] = 0x2c,
|
||||
[TIMER_TCLR] = 0x38,
|
||||
[TIMER_TCRR] = 0x3c,
|
||||
[TIMER_TLDR] = 0x40,
|
||||
},
|
||||
[DM_TIMER_OMAP3430] = {
|
||||
[TIMER_TISR] = 0x18,
|
||||
[TIMER_TIER] = 0x1c,
|
||||
[TIMER_TCLR] = 0x24,
|
||||
[TIMER_TCRR] = 0x28,
|
||||
[TIMER_TLDR] = 0x2c,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct of_compat_data compat_data[] = {
|
||||
{ "ti,am335x-timer-1ms", DM_TIMER_AM335X },
|
||||
{ "ti,am335x-timer", DM_TIMER_AM335X },
|
||||
{ "ti,omap3430-timer", DM_TIMER_OMAP3430 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
struct omaptimer_softc {
|
||||
|
@ -26,10 +73,15 @@ struct omaptimer_softc {
|
|||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
int sc_phandle;
|
||||
struct clk *sc_clk;
|
||||
enum omaptimer_type sc_type;
|
||||
struct timecounter sc_tc;
|
||||
};
|
||||
|
||||
#define RD4(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, omaptimer_regmap[(sc)->sc_type][(reg)])
|
||||
#define WR4(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, omaptimer_regmap[(sc)->sc_type][(reg)], val)
|
||||
|
||||
static struct omaptimer_softc *timer_softc;
|
||||
|
||||
static int
|
||||
|
@ -38,7 +90,7 @@ omaptimer_intr(void *arg)
|
|||
struct omaptimer_softc * const sc = timer_softc;
|
||||
struct clockframe * const frame = arg;
|
||||
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, 0x28, 2);
|
||||
WR4(sc, TIMER_TISR, OVF_IT_FLAG);
|
||||
hardclock(frame);
|
||||
|
||||
return 1;
|
||||
|
@ -61,12 +113,26 @@ omaptimer_cpu_initclocks(void)
|
|||
|
||||
aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr);
|
||||
|
||||
uint32_t value;
|
||||
value = (0xffffffff - ((24000000UL / hz) - 1));
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, 0x40, value);
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, 0x3c, value);
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, 0x2c, 2);
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, 0x38, 3);
|
||||
/* Enable interrupts */
|
||||
WR4(sc, TIMER_TIER, OVF_EN_FLAG);
|
||||
}
|
||||
|
||||
static u_int
|
||||
omaptimer_get_timecount(struct timecounter *tc)
|
||||
{
|
||||
struct omaptimer_softc * const sc = tc->tc_priv;
|
||||
|
||||
return RD4(sc, TIMER_TCRR);
|
||||
}
|
||||
|
||||
static void
|
||||
omaptimer_enable(struct omaptimer_softc *sc, uint32_t value)
|
||||
{
|
||||
/* Configure the timer */
|
||||
WR4(sc, TIMER_TLDR, value);
|
||||
WR4(sc, TIMER_TCRR, value);
|
||||
WR4(sc, TIMER_TIER, 0);
|
||||
WR4(sc, TIMER_TCLR, TCLR_ST | TCLR_AR);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -74,7 +140,7 @@ omaptimer_match(device_t parent, cfdata_t match, void *aux)
|
|||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
return of_match_compat_data(faa->faa_phandle, compat_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -83,37 +149,64 @@ omaptimer_attach(device_t parent, device_t self, void *aux)
|
|||
struct omaptimer_softc * const sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
struct timecounter *tc = &sc->sc_tc;
|
||||
const char *modname;
|
||||
struct clk *hwmod;
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
u_int rate;
|
||||
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ((sc->sc_clk = fdtbus_clock_get_index(phandle, 0)) == NULL) {
|
||||
aprint_error(": couldn't get clock\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_phandle = phandle;
|
||||
sc->sc_bst = faa->faa_bst;
|
||||
sc->sc_type = of_search_compatible(phandle, compat_data)->data;
|
||||
|
||||
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
|
||||
device_printf(self, "unable to map bus space");
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": Timer\n");
|
||||
hwmod = ti_prcm_get_hwmod(phandle, 0);
|
||||
if (hwmod == NULL || clk_enable(hwmod) != 0) {
|
||||
aprint_error(": couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Use this as the OS timer in UP configurations */
|
||||
if (!arm_has_mpext_p && addr == 0x48042000) { /* TIMER3 */
|
||||
timer_softc = sc;
|
||||
arm_fdt_timer_register(omaptimer_cpu_initclocks);
|
||||
modname = fdtbus_get_string(phandle, "ti,hwmods");
|
||||
if (modname == NULL)
|
||||
modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods");
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": Timer (%s)\n", modname);
|
||||
|
||||
rate = clk_get_rate(hwmod);
|
||||
|
||||
if (strcmp(modname, "timer2") == 0) {
|
||||
omaptimer_enable(sc, 0);
|
||||
|
||||
/* Install timecounter */
|
||||
tc->tc_get_timecount = omaptimer_get_timecount;
|
||||
tc->tc_counter_mask = ~0u;
|
||||
tc->tc_frequency = rate;
|
||||
tc->tc_name = modname;
|
||||
tc->tc_quality = 200;
|
||||
tc->tc_priv = sc;
|
||||
tc_init(tc);
|
||||
|
||||
} else if (strcmp(modname, "timer3") == 0) {
|
||||
const uint32_t value = (0xffffffff - ((rate / hz) - 1));
|
||||
omaptimer_enable(sc, value);
|
||||
|
||||
/* Use this as the OS timer in UP configurations */
|
||||
if (!arm_has_mpext_p) {
|
||||
timer_softc = sc;
|
||||
arm_fdt_timer_register(omaptimer_cpu_initclocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/* $NetBSD: ti_otg.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Manuel Bouyer. 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: ti_otg.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
#include <arm/ti/ti_otgreg.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
static const char * compatible [] = {
|
||||
"ti,am33xx-usb",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct tiotg_softc {
|
||||
device_t sc_dev;
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ioh;
|
||||
bus_dma_tag_t sc_dmat;
|
||||
void * sc_ih;
|
||||
};
|
||||
|
||||
static int tiotg_match(device_t, cfdata_t, void *);
|
||||
static void tiotg_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_otg, sizeof(struct tiotg_softc),
|
||||
tiotg_match, tiotg_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
tiotg_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
tiotg_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct tiotg_softc *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;
|
||||
uint32_t val;
|
||||
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_iot = faa->faa_bst;
|
||||
sc->sc_dmat = faa->faa_dmat;
|
||||
sc->sc_dev = self;
|
||||
|
||||
if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_normal(": TI dual-port USB controller");
|
||||
|
||||
#if 0
|
||||
/* XXX this looks wrong */
|
||||
prcm_write_4(AM335X_PRCM_CM_WKUP, CM_WKUP_CM_CLKDCOLDO_DPLL_PER,
|
||||
CM_WKUP_CM_CLKDCOLDO_DPLL_PER_CLKDCOLDO_GATE_CTRL|
|
||||
CM_WKUP_CM_CLKDCOLDO_DPLL_PER_CLKDCOLDO_ST);
|
||||
|
||||
prcm_write_4(AM335X_PRCM_CM_PER, CM_PER_USB0_CLKCTRL, 2);
|
||||
while ((prcm_read_4(AM335X_PRCM_CM_PER, CM_PER_USB0_CLKCTRL) & 0x3) != 2)
|
||||
delay(10);
|
||||
|
||||
while (prcm_read_4(AM335X_PRCM_CM_PER, CM_PER_USB0_CLKCTRL) & (3<<16))
|
||||
delay(10);
|
||||
#endif
|
||||
|
||||
/* reset module */
|
||||
TIOTG_USBSS_WRITE4(sc, USBSS_SYSCONFIG, USBSS_SYSCONFIG_SRESET);
|
||||
while (TIOTG_USBSS_READ4(sc, USBSS_SYSCONFIG) & USBSS_SYSCONFIG_SRESET)
|
||||
delay(10);
|
||||
val = TIOTG_USBSS_READ4(sc, USBSS_REVREG);
|
||||
aprint_normal(": version v%d.%d.%d.%d",
|
||||
(val >> 11) & 15, (val >> 8) & 7, (val >> 6) & 3, val & 63);
|
||||
aprint_normal("\n");
|
||||
|
||||
/* enable clock */
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fdt_add_bus(self, phandle, faa);
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/* $NetBSD: ti_otgreg.h,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Manuel Bouyer. 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.
|
||||
*/
|
||||
|
||||
#define TI_OTG_NPORTS 2
|
||||
/* USBSS registers */
|
||||
#define TIOTG_USBSS_OFFSET 0
|
||||
#define TIOTG_USBSS_READ4(sc, reg) \
|
||||
bus_space_read_4(sc->sc_iot, sc->sc_ioh, (reg) + TIOTG_USBSS_OFFSET)
|
||||
#define TIOTG_USBSS_WRITE4(sc, reg, val) \
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_ioh, (reg) + TIOTG_USBSS_OFFSET, (val))
|
||||
|
||||
#define USBSS_REVREG 0x00
|
||||
#define USBSS_SYSCONFIG 0x10
|
||||
#define USBSS_SYSCONFIG_USB0_OCP_EN_N 0x800
|
||||
#define USBSS_SYSCONFIG_PHY0_UTMI_EN_N 0x400
|
||||
#define USBSS_SYSCONFIG_USB1_OCP_EN_N 0x200
|
||||
#define USBSS_SYSCONFIG_PHY1_UTMI_EN_N 0x100
|
||||
#define USBSS_SYSCONFIG_STBYMODE_SHIFT 4
|
||||
#define USBSS_SYSCONFIG_IDLEMODE_SHIFT 2
|
||||
#define USBSS_SYSCONFIG_FREEEMU 0x002
|
||||
#define USBSS_SYSCONFIG_SRESET 0x001
|
||||
|
||||
/* USB control registers */
|
||||
#define USB_CTRL_OFFSET(port) (0x1000 + (0x800 * (port)))
|
||||
#define USB_PORT_SIZE 0x800 /* size of CTRL+PHY+CORE */
|
||||
#define TIOTG_USBC_READ4(sc, reg) \
|
||||
bus_space_read_4(sc->sc_ctrliot, sc->sc_ctrlioh, (reg))
|
||||
#define TIOTG_USBC_WRITE4(sc, reg, val) \
|
||||
bus_space_write_4(sc->sc_ctrliot, sc->sc_ctrlioh, (reg), (val))
|
||||
|
||||
#define USBCTRL_REV 0x00
|
||||
#define USBCTRL_CTRL 0x14
|
||||
#define USBCTRL_STAT 0x18
|
||||
#define USBCTRL_IRQ_STAT0 0x30
|
||||
#define USBCTRL_IRQ_STAT0_RXSHIFT 16
|
||||
#define USBCTRL_IRQ_STAT0_TXSHIFT 0
|
||||
#define USBCTRL_IRQ_STAT1 0x34
|
||||
#define USBCTRL_IRQ_STAT1_DRVVBUS (1 << 8)
|
||||
#define USBCTRL_INTEN_SET0 0x38
|
||||
#define USBCTRL_INTEN_SET1 0x3C
|
||||
#define USBCTRL_INTEN_USB_ALL 0x1ff
|
||||
#define USBCTRL_INTEN_USB_SOF (1 << 3)
|
||||
#define USBCTRL_INTEN_CLR0 0x40
|
||||
#define USBCTRL_INTEN_CLR1 0x44
|
||||
#define USBCTRL_UTMI 0xE0
|
||||
#define USBCTRL_UTMI_FSDATAEXT (1 << 1)
|
||||
#define USBCTRL_MODE 0xE8
|
||||
#define USBCTRL_MODE_IDDIG (1 << 8)
|
||||
#define USBCTRL_MODE_IDDIGMUX (1 << 7)
|
||||
|
||||
#define USB_CORE_OFFSET 0x400
|
||||
#define USB_CORE_SIZE 0x400
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef _ARM_TI_TI_PLATFORM_H_
|
||||
#define _ARM_TI_TI_PLATFORM_H_
|
||||
|
||||
#define TI_CORE_VBASE 0xe4c00000
|
||||
#define TI_CORE_PBASE 0x44c00000
|
||||
#define TI_CORE_SIZE 0x00400000
|
||||
|
||||
#endif /* _ARM_TI_TI_PLATFORM_H_ */
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ti_prcm.c,v 1.1 2017/10/26 23:28:15 jmcneill Exp $ */
|
||||
/* $NetBSD: ti_prcm.c,v 1.1.10.1 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_prcm.c,v 1.1 2017/10/26 23:28:15 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_prcm.c,v 1.1.10.1 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -228,12 +228,15 @@ ti_prcm_get_hwmod(const int phandle, u_int index)
|
|||
{
|
||||
struct ti_prcm_clk *tc;
|
||||
const char *hwmods, *p;
|
||||
int len, resid;
|
||||
int len, resid, hwmod_phandle;
|
||||
u_int n;
|
||||
|
||||
KASSERTMSG(prcm_softc != NULL, "prcm driver not attached");
|
||||
|
||||
hwmods = fdtbus_get_prop(phandle, "ti,hwmods", &len);
|
||||
/* If this node does not have a ti,hwmods property, try the parent */
|
||||
hwmod_phandle = of_hasprop(phandle, "ti,hwmods") ? phandle : OF_parent(phandle);
|
||||
|
||||
hwmods = fdtbus_get_prop(hwmod_phandle, "ti,hwmods", &len);
|
||||
if (len <= 0)
|
||||
return NULL;
|
||||
|
||||
|
@ -255,3 +258,15 @@ ti_prcm_get_hwmod(const int phandle, u_int index)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
ti_prcm_enable_hwmod(const int phandle, u_int index)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = ti_prcm_get_hwmod(phandle, index);
|
||||
if (clk == NULL)
|
||||
return ENOENT;
|
||||
|
||||
return clk_enable(clk);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ti_prcm.h,v 1.1 2017/10/26 23:28:15 jmcneill Exp $ */
|
||||
/* $NetBSD: ti_prcm.h,v 1.1.10.1 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
|
||||
|
@ -55,9 +55,13 @@ struct ti_prcm_fixed_factor {
|
|||
|
||||
struct ti_prcm_hwmod {
|
||||
bus_size_t reg;
|
||||
uint32_t mask;
|
||||
const char *parent;
|
||||
u_int flags;
|
||||
};
|
||||
|
||||
#define TI_HWMOD_DISABLE_AUTOIDLE 0x01
|
||||
|
||||
struct ti_prcm_clk {
|
||||
struct clk base;
|
||||
enum ti_prcm_clktype type;
|
||||
|
@ -137,9 +141,14 @@ ti_prcm_hwmod_get_parent(struct ti_prcm_softc *sc, struct ti_prcm_clk *tc)
|
|||
}
|
||||
|
||||
#define TI_PRCM_HWMOD(_name, _reg, _parent, _enable) \
|
||||
TI_PRCM_HWMOD_MASK(_name, _reg, 0, _parent, _enable, 0)
|
||||
|
||||
#define TI_PRCM_HWMOD_MASK(_name, _reg, _mask, _parent, _enable, _flags) \
|
||||
{ \
|
||||
.type = TI_PRCM_HWMOD, .base.name = (_name), \
|
||||
.u.hwmod.reg = (_reg), \
|
||||
.u.hwmod.mask = (_mask), \
|
||||
.u.hwmod.flags = (_flags), \
|
||||
.u.hwmod.parent = (_parent), \
|
||||
.enable = (_enable), \
|
||||
.get_parent = ti_prcm_hwmod_get_parent, \
|
||||
|
@ -165,5 +174,6 @@ struct ti_prcm_softc {
|
|||
#endif /* !TI_PRCM_PRIVATE */
|
||||
|
||||
struct clk * ti_prcm_get_hwmod(const int, u_int);
|
||||
int ti_prcm_enable_hwmod(const int, u_int);
|
||||
|
||||
#endif /* !_ARM_TI_PRCM_H */
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/* $NetBSD: ti_rng.c,v 1.2.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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: ti_rng.c,v 1.2.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rndpool.h>
|
||||
#include <sys/rndsource.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
#include <arm/ti/ti_rngreg.h>
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,omap4-rng",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct ti_rng_softc {
|
||||
device_t sc_dev;
|
||||
bus_space_tag_t sc_iot;
|
||||
bus_space_handle_t sc_ioh;
|
||||
|
||||
kmutex_t sc_lock;
|
||||
krndsource_t sc_rndsource;
|
||||
};
|
||||
|
||||
static int ti_rng_match(device_t, cfdata_t, void *);
|
||||
static void ti_rng_attach(device_t, device_t, void *);
|
||||
static void ti_rng_callback(size_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_rng, sizeof(struct ti_rng_softc),
|
||||
ti_rng_match, ti_rng_attach, NULL, NULL);
|
||||
|
||||
#define RD4(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))
|
||||
#define WR4(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
|
||||
|
||||
static int
|
||||
ti_rng_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_rng_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_rng_softc *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;
|
||||
}
|
||||
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_iot = faa->faa_bst;
|
||||
if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
|
||||
if ((RD4(sc, TRNG_CONTROL_REG) & TRNG_CONTROL_ENABLE) == 0) {
|
||||
WR4(sc, TRNG_CONFIG_REG,
|
||||
__SHIFTIN(0x21, TRNG_CONFIG_MIN_REFILL) |
|
||||
__SHIFTIN(0x22, TRNG_CONFIG_MAX_REFILL));
|
||||
WR4(sc, TRNG_CONTROL_REG,
|
||||
__SHIFTIN(0x21, TRNG_CONTROL_STARTUP_CYCLES) |
|
||||
TRNG_CONTROL_ENABLE);
|
||||
}
|
||||
|
||||
rndsource_setcb(&sc->sc_rndsource, ti_rng_callback, sc);
|
||||
rnd_attach_source(&sc->sc_rndsource, device_xname(self), RND_TYPE_RNG,
|
||||
RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB);
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": RNG\n");
|
||||
|
||||
ti_rng_callback(RND_POOLBITS / NBBY, sc);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_rng_callback(size_t bytes_wanted, void *priv)
|
||||
{
|
||||
struct ti_rng_softc * const sc = priv;
|
||||
uint32_t buf[2];
|
||||
u_int retry;
|
||||
|
||||
mutex_enter(&sc->sc_lock);
|
||||
while (bytes_wanted) {
|
||||
for (retry = 10; retry > 0; retry--) {
|
||||
if (RD4(sc, TRNG_STATUS_REG) & TRNG_STATUS_READY)
|
||||
break;
|
||||
delay(10);
|
||||
}
|
||||
if (retry == 0)
|
||||
break;
|
||||
buf[0] = RD4(sc, TRNG_OUTPUT_L_REG);
|
||||
buf[1] = RD4(sc, TRNG_OUTPUT_H_REG);
|
||||
WR4(sc, TRNG_INTACK_REG, TRNG_INTACK_READY);
|
||||
rnd_add_data_sync(&sc->sc_rndsource, buf, sizeof(buf),
|
||||
sizeof(buf) * NBBY);
|
||||
bytes_wanted -= MIN(bytes_wanted, sizeof(buf));
|
||||
}
|
||||
explicit_memset(buf, 0, sizeof(buf));
|
||||
mutex_exit(&sc->sc_lock);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* $NetBSD: ti_rngreg.h,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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 _TI_RNGREG_H
|
||||
#define _TI_RNGREG_H
|
||||
|
||||
#define TRNG_OUTPUT_L_REG 0x00
|
||||
#define TRNG_OUTPUT_H_REG 0x04
|
||||
#define TRNG_STATUS_REG 0x08
|
||||
#define TRNG_STATUS_READY __BIT(0)
|
||||
#define TRNG_INTACK_REG 0x10
|
||||
#define TRNG_INTACK_READY __BIT(0)
|
||||
#define TRNG_CONTROL_REG 0x14
|
||||
#define TRNG_CONTROL_STARTUP_CYCLES __BITS(31,16)
|
||||
#define TRNG_CONTROL_ENABLE __BIT(10)
|
||||
#define TRNG_CONFIG_REG 0x18
|
||||
#define TRNG_CONFIG_MAX_REFILL __BITS(31,16)
|
||||
#define TRNG_CONFIG_MIN_REFILL __BITS(7,0)
|
||||
|
||||
#endif /* !_TI_RNGREG_H */
|
|
@ -0,0 +1,676 @@
|
|||
/* $NetBSD: ti_sdhc.c,v 1.3.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2011 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 <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_sdhc.c,v 1.3.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
#include <arm/ti/ti_edma.h>
|
||||
#include <arm/ti/ti_sdhcreg.h>
|
||||
|
||||
#include <dev/sdmmc/sdhcreg.h>
|
||||
#include <dev/sdmmc/sdhcvar.h>
|
||||
#include <dev/sdmmc/sdmmcvar.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#define EDMA_MAX_PARAMS 32
|
||||
|
||||
#ifdef TISDHC_DEBUG
|
||||
int tisdhcdebug = 1;
|
||||
#define DPRINTF(n,s) do { if ((n) <= tisdhcdebug) device_printf s; } while (0)
|
||||
#else
|
||||
#define DPRINTF(n,s) do {} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
#define CLKD(kz) (sc->sc.sc_clkbase / (kz))
|
||||
|
||||
#define SDHC_READ(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_sdhc_bsh, (reg))
|
||||
#define SDHC_WRITE(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_sdhc_bsh, (reg), (val))
|
||||
|
||||
struct ti_sdhc_config {
|
||||
bus_size_t regoff;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
static const struct ti_sdhc_config omap2_hsmmc_config = {
|
||||
};
|
||||
|
||||
static const struct ti_sdhc_config omap3_pre_es3_hsmmc_config = {
|
||||
.flags = SDHC_FLAG_SINGLE_ONLY
|
||||
};
|
||||
|
||||
static const struct ti_sdhc_config omap4_hsmmc_config = {
|
||||
.regoff = 0x100
|
||||
};
|
||||
|
||||
static const struct of_compat_data compat_data[] = {
|
||||
{ "ti,omap2-hsmmc", (uintptr_t)&omap2_hsmmc_config },
|
||||
{ "ti,omap3-hsmmc", (uintptr_t)&omap2_hsmmc_config },
|
||||
{ "ti,omap3-pre-es3-hsmmc", (uintptr_t)&omap3_pre_es3_hsmmc_config },
|
||||
{ "ti,omap4-hsmmc", (uintptr_t)&omap4_hsmmc_config },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
enum {
|
||||
EDMA_CHAN_TX,
|
||||
EDMA_CHAN_RX,
|
||||
EDMA_NCHAN
|
||||
};
|
||||
|
||||
struct ti_sdhc_softc {
|
||||
struct sdhc_softc sc;
|
||||
int sc_phandle;
|
||||
bus_addr_t sc_addr;
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
bus_space_handle_t sc_hl_bsh;
|
||||
bus_space_handle_t sc_sdhc_bsh;
|
||||
struct sdhc_host *sc_hosts[1];
|
||||
void *sc_ih; /* interrupt vectoring */
|
||||
|
||||
int sc_edma_chan[EDMA_NCHAN];
|
||||
struct edma_channel *sc_edma_tx;
|
||||
struct edma_channel *sc_edma_rx;
|
||||
uint16_t sc_edma_param_tx[EDMA_MAX_PARAMS];
|
||||
uint16_t sc_edma_param_rx[EDMA_MAX_PARAMS];
|
||||
kcondvar_t sc_edma_cv;
|
||||
bus_addr_t sc_edma_fifo;
|
||||
bool sc_edma_pending;
|
||||
bus_dmamap_t sc_edma_dmamap;
|
||||
bus_dma_segment_t sc_edma_segs[1];
|
||||
void *sc_edma_bbuf;
|
||||
};
|
||||
|
||||
static int ti_sdhc_match(device_t, cfdata_t, void *);
|
||||
static void ti_sdhc_attach(device_t, device_t, void *);
|
||||
|
||||
static void ti_sdhc_init(struct ti_sdhc_softc *, const struct ti_sdhc_config *);
|
||||
|
||||
static int ti_sdhc_bus_width(struct sdhc_softc *, int);
|
||||
static int ti_sdhc_rod(struct sdhc_softc *, int);
|
||||
static int ti_sdhc_write_protect(struct sdhc_softc *);
|
||||
static int ti_sdhc_card_detect(struct sdhc_softc *);
|
||||
|
||||
static int ti_sdhc_edma_init(struct ti_sdhc_softc *, u_int, u_int);
|
||||
static int ti_sdhc_edma_xfer_data(struct sdhc_softc *, struct sdmmc_command *);
|
||||
static void ti_sdhc_edma_done(void *);
|
||||
static int ti_sdhc_edma_transfer(struct sdhc_softc *, struct sdmmc_command *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_sdhc, sizeof(struct ti_sdhc_softc),
|
||||
ti_sdhc_match, ti_sdhc_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
ti_sdhc_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
|
||||
ti_sdhc_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_sdhc_softc * const sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
const struct ti_sdhc_config *conf;
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
u_int bus_width;
|
||||
|
||||
conf = (const void *)of_search_compatible(phandle, compat_data)->data;
|
||||
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0 || size <= conf->regoff) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
return;
|
||||
}
|
||||
addr += conf->regoff;
|
||||
size -= conf->regoff;
|
||||
|
||||
sc->sc.sc_dmat = faa->faa_dmat;
|
||||
sc->sc.sc_dev = self;
|
||||
sc->sc_phandle = phandle;
|
||||
sc->sc_addr = addr;
|
||||
sc->sc_bst = faa->faa_bst;
|
||||
|
||||
#if notyet
|
||||
/* XXX use fdtbus_dma API */
|
||||
int len;
|
||||
const u_int *dmas = fdtbus_get_prop(phandle, "dmas", &len);
|
||||
switch (len) {
|
||||
case 24:
|
||||
sc->sc_edma_chan[EDMA_CHAN_TX] = be32toh(dmas[1]);
|
||||
sc->sc_edma_chan[EDMA_CHAN_RX] = be32toh(dmas[4]);
|
||||
break;
|
||||
case 32:
|
||||
sc->sc_edma_chan[EDMA_CHAN_TX] = be32toh(dmas[1]);
|
||||
sc->sc_edma_chan[EDMA_CHAN_RX] = be32toh(dmas[5]);
|
||||
break;
|
||||
default:
|
||||
sc->sc_edma_chan[EDMA_CHAN_TX] = -1;
|
||||
sc->sc_edma_chan[EDMA_CHAN_RX] = -1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
sc->sc_edma_chan[EDMA_CHAN_TX] = -1;
|
||||
sc->sc_edma_chan[EDMA_CHAN_RX] = -1;
|
||||
#endif
|
||||
|
||||
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (of_getprop_uint32(phandle, "bus-width", &bus_width) != 0)
|
||||
bus_width = 4;
|
||||
|
||||
sc->sc.sc_flags |= conf->flags;
|
||||
sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS;
|
||||
sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON;
|
||||
sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC;
|
||||
if (bus_width == 8)
|
||||
sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE;
|
||||
if (of_hasprop(phandle, "ti,needs-special-reset"))
|
||||
sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET;
|
||||
if (of_hasprop(phandle, "ti,needs-special-hs-handling"))
|
||||
sc->sc.sc_flags |= SDHC_FLAG_NO_HS_BIT;
|
||||
if (of_hasprop(phandle, "ti,dual-volt"))
|
||||
sc->sc.sc_caps = SDHC_VOLTAGE_SUPP_3_0V;
|
||||
|
||||
sc->sc.sc_host = sc->sc_hosts;
|
||||
sc->sc.sc_clkbase = 96000; /* 96MHZ */
|
||||
sc->sc.sc_clkmsk = 0x0000ffc0;
|
||||
sc->sc.sc_vendor_rod = ti_sdhc_rod;
|
||||
sc->sc.sc_vendor_write_protect = ti_sdhc_write_protect;
|
||||
sc->sc.sc_vendor_card_detect = ti_sdhc_card_detect;
|
||||
sc->sc.sc_vendor_bus_width = ti_sdhc_bus_width;
|
||||
|
||||
if (bus_space_subregion(sc->sc_bst, sc->sc_bsh, 0x100, 0x100,
|
||||
&sc->sc_sdhc_bsh) != 0) {
|
||||
aprint_error(": couldn't map subregion\n");
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": MMCHS\n");
|
||||
|
||||
ti_sdhc_init(sc, conf);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_sdhc_init(struct ti_sdhc_softc *sc, const struct ti_sdhc_config *conf)
|
||||
{
|
||||
device_t dev = sc->sc.sc_dev;
|
||||
uint32_t clkd, stat;
|
||||
int error, timo, clksft, n;
|
||||
char intrstr[128];
|
||||
|
||||
const int tx_chan = sc->sc_edma_chan[EDMA_CHAN_TX];
|
||||
const int rx_chan = sc->sc_edma_chan[EDMA_CHAN_RX];
|
||||
|
||||
if (tx_chan != -1 && rx_chan != -1) {
|
||||
aprint_normal_dev(dev,
|
||||
"EDMA tx channel %d, rx channel %d\n",
|
||||
tx_chan, rx_chan);
|
||||
|
||||
if (ti_sdhc_edma_init(sc, tx_chan, rx_chan) != 0) {
|
||||
aprint_error_dev(dev, "EDMA disabled\n");
|
||||
goto no_dma;
|
||||
}
|
||||
|
||||
cv_init(&sc->sc_edma_cv, "sdhcedma");
|
||||
sc->sc_edma_fifo = sc->sc_addr + 0x100 + SDHC_DATA;
|
||||
sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
|
||||
sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA;
|
||||
sc->sc.sc_flags |= SDHC_FLAG_EXTDMA_DMAEN;
|
||||
sc->sc.sc_vendor_transfer_data_dma = ti_sdhc_edma_xfer_data;
|
||||
}
|
||||
no_dma:
|
||||
|
||||
/* XXXXXX: Turn-on regulator via I2C. */
|
||||
/* XXXXXX: And enable ICLOCK/FCLOCK. */
|
||||
|
||||
SDHC_WRITE(sc, SDHC_CAPABILITIES,
|
||||
SDHC_READ(sc, SDHC_CAPABILITIES) | SDHC_VOLTAGE_SUPP_1_8V);
|
||||
if (sc->sc.sc_caps & SDHC_VOLTAGE_SUPP_3_0V)
|
||||
SDHC_WRITE(sc, SDHC_CAPABILITIES,
|
||||
SDHC_READ(sc, SDHC_CAPABILITIES) | SDHC_VOLTAGE_SUPP_3_0V);
|
||||
|
||||
/* MMCHS Soft reset */
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
|
||||
SYSCONFIG_SOFTRESET);
|
||||
timo = 3000000; /* XXXX 3 sec. */
|
||||
while (timo--) {
|
||||
if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSSTATUS) &
|
||||
SYSSTATUS_RESETDONE)
|
||||
break;
|
||||
delay(1);
|
||||
}
|
||||
if (timo == 0)
|
||||
aprint_error_dev(dev, "Soft reset timeout\n");
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
|
||||
SYSCONFIG_ENAWAKEUP |
|
||||
#if notyet
|
||||
SYSCONFIG_AUTOIDLE |
|
||||
SYSCONFIG_SIDLEMODE_AUTO |
|
||||
#else
|
||||
SYSCONFIG_SIDLEMODE_IGNORE |
|
||||
#endif
|
||||
SYSCONFIG_CLOCKACTIVITY_FCLK |
|
||||
SYSCONFIG_CLOCKACTIVITY_ICLK);
|
||||
|
||||
if (!fdtbus_intr_str(sc->sc_phandle, 0, intrstr, sizeof(intrstr))) {
|
||||
aprint_error_dev(dev, "couldn't decode interrupt\n");
|
||||
return;
|
||||
}
|
||||
sc->sc_ih = fdtbus_intr_establish(sc->sc_phandle, 0, IPL_VM,
|
||||
0, sdhc_intr, &sc->sc);
|
||||
if (sc->sc_ih == NULL) {
|
||||
aprint_error_dev(dev, "couldn't establish interrupt\n");
|
||||
return;
|
||||
}
|
||||
aprint_normal_dev(dev, "interrupting on %s\n", intrstr);
|
||||
|
||||
error = sdhc_host_found(&sc->sc, sc->sc_bst, sc->sc_sdhc_bsh, 0x100);
|
||||
if (error != 0) {
|
||||
aprint_error_dev(dev, "couldn't initialize host, error=%d\n",
|
||||
error);
|
||||
fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih);
|
||||
return;
|
||||
}
|
||||
|
||||
clksft = ffs(sc->sc.sc_clkmsk) - 1;
|
||||
|
||||
/* Set SDVS 1.8v and DTW 1bit mode */
|
||||
SDHC_WRITE(sc, SDHC_HOST_CTL,
|
||||
SDHC_VOLTAGE_1_8V << (SDHC_VOLTAGE_SHIFT + 8));
|
||||
SDHC_WRITE(sc, SDHC_CLOCK_CTL,
|
||||
SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_INTCLK_ENABLE |
|
||||
SDHC_SDCLK_ENABLE);
|
||||
SDHC_WRITE(sc, SDHC_HOST_CTL,
|
||||
SDHC_READ(sc, SDHC_HOST_CTL) | SDHC_BUS_POWER << 8);
|
||||
SDHC_WRITE(sc, SDHC_CLOCK_CTL,
|
||||
SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);
|
||||
|
||||
/*
|
||||
* 22.6.1.3.1.5 MMCHS Controller INIT Procedure Start
|
||||
* from 'OMAP35x Applications Processor Technical Reference Manual'.
|
||||
*
|
||||
* During the INIT procedure, the MMCHS controller generates 80 clock
|
||||
* periods. In order to keep the 1ms gap, the MMCHS controller should
|
||||
* be configured to generate a clock whose frequency is smaller or
|
||||
* equal to 80 KHz.
|
||||
*/
|
||||
|
||||
SDHC_WRITE(sc, SDHC_CLOCK_CTL,
|
||||
SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
|
||||
SDHC_WRITE(sc, SDHC_CLOCK_CTL,
|
||||
SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
|
||||
clkd = CLKD(80);
|
||||
n = 1;
|
||||
while (clkd & ~(sc->sc.sc_clkmsk >> clksft)) {
|
||||
clkd >>= 1;
|
||||
n <<= 1;
|
||||
}
|
||||
SDHC_WRITE(sc, SDHC_CLOCK_CTL,
|
||||
SDHC_READ(sc, SDHC_CLOCK_CTL) | (clkd << clksft));
|
||||
SDHC_WRITE(sc, SDHC_CLOCK_CTL,
|
||||
SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);
|
||||
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
|
||||
bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_INIT);
|
||||
SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000);
|
||||
delay(1000);
|
||||
stat = SDHC_READ(sc, SDHC_NINTR_STATUS);
|
||||
SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat | SDHC_COMMAND_COMPLETE);
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
|
||||
bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) & ~CON_INIT);
|
||||
SDHC_WRITE(sc, SDHC_NINTR_STATUS, 0xffffffff);
|
||||
|
||||
SDHC_WRITE(sc, SDHC_CLOCK_CTL,
|
||||
SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
|
||||
SDHC_WRITE(sc, SDHC_CLOCK_CTL,
|
||||
SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
|
||||
SDHC_WRITE(sc, SDHC_CLOCK_CTL,
|
||||
SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);
|
||||
timo = 3000000; /* XXXX 3 sec. */
|
||||
while (--timo) {
|
||||
if (SDHC_READ(sc, SDHC_CLOCK_CTL) & SDHC_INTCLK_STABLE)
|
||||
break;
|
||||
delay(1);
|
||||
}
|
||||
if (timo == 0)
|
||||
aprint_error_dev(dev, "ICS timeout\n");
|
||||
SDHC_WRITE(sc, SDHC_CLOCK_CTL,
|
||||
SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);
|
||||
|
||||
if (sc->sc.sc_flags & SDHC_FLAG_USE_ADMA2)
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
|
||||
bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) |
|
||||
CON_MNS);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_sdhc_rod(struct sdhc_softc *sc, int on)
|
||||
{
|
||||
struct ti_sdhc_softc *hmsc = (struct ti_sdhc_softc *)sc;
|
||||
uint32_t con;
|
||||
|
||||
con = bus_space_read_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON);
|
||||
if (on)
|
||||
con |= CON_OD;
|
||||
else
|
||||
con &= ~CON_OD;
|
||||
bus_space_write_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON, con);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ti_sdhc_write_protect(struct sdhc_softc *sc)
|
||||
{
|
||||
|
||||
/* Maybe board dependent, using GPIO. Get GPIO-pin from prop? */
|
||||
return 0; /* XXXXXXX */
|
||||
}
|
||||
|
||||
static int
|
||||
ti_sdhc_card_detect(struct sdhc_softc *sc)
|
||||
{
|
||||
|
||||
/* Maybe board dependent, using GPIO. Get GPIO-pin from prop? */
|
||||
return 1; /* XXXXXXXX */
|
||||
}
|
||||
|
||||
static int
|
||||
ti_sdhc_bus_width(struct sdhc_softc *sc, int width)
|
||||
{
|
||||
struct ti_sdhc_softc *hmsc = (struct ti_sdhc_softc *)sc;
|
||||
uint32_t con;
|
||||
|
||||
con = bus_space_read_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON);
|
||||
if (width == 8) {
|
||||
con |= CON_DW8;
|
||||
} else {
|
||||
con &= ~CON_DW8;
|
||||
}
|
||||
bus_space_write_4(hmsc->sc_bst, hmsc->sc_bsh, MMCHS_CON, con);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ti_sdhc_edma_init(struct ti_sdhc_softc *sc, u_int tx_chan, u_int rx_chan)
|
||||
{
|
||||
int i, error, rseg;
|
||||
|
||||
/* Request tx and rx DMA channels */
|
||||
sc->sc_edma_tx = edma_channel_alloc(EDMA_TYPE_DMA, tx_chan,
|
||||
ti_sdhc_edma_done, sc);
|
||||
KASSERT(sc->sc_edma_tx != NULL);
|
||||
sc->sc_edma_rx = edma_channel_alloc(EDMA_TYPE_DMA, rx_chan,
|
||||
ti_sdhc_edma_done, sc);
|
||||
KASSERT(sc->sc_edma_rx != NULL);
|
||||
|
||||
/* Allocate some PaRAM pages */
|
||||
for (i = 0; i < __arraycount(sc->sc_edma_param_tx); i++) {
|
||||
sc->sc_edma_param_tx[i] = edma_param_alloc(sc->sc_edma_tx);
|
||||
KASSERT(sc->sc_edma_param_tx[i] != 0xffff);
|
||||
}
|
||||
for (i = 0; i < __arraycount(sc->sc_edma_param_rx); i++) {
|
||||
sc->sc_edma_param_rx[i] = edma_param_alloc(sc->sc_edma_rx);
|
||||
KASSERT(sc->sc_edma_param_rx[i] != 0xffff);
|
||||
}
|
||||
|
||||
/* Setup bounce buffer */
|
||||
error = bus_dmamem_alloc(sc->sc.sc_dmat, MAXPHYS, 32, MAXPHYS,
|
||||
sc->sc_edma_segs, 1, &rseg, BUS_DMA_WAITOK);
|
||||
if (error) {
|
||||
aprint_error_dev(sc->sc.sc_dev,
|
||||
"couldn't allocate dmamem: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
KASSERT(rseg == 1);
|
||||
error = bus_dmamem_map(sc->sc.sc_dmat, sc->sc_edma_segs, rseg, MAXPHYS,
|
||||
&sc->sc_edma_bbuf, BUS_DMA_WAITOK);
|
||||
if (error) {
|
||||
aprint_error_dev(sc->sc.sc_dev, "couldn't map dmamem: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
error = bus_dmamap_create(sc->sc.sc_dmat, MAXPHYS, 1, MAXPHYS, 0,
|
||||
BUS_DMA_WAITOK, &sc->sc_edma_dmamap);
|
||||
if (error) {
|
||||
aprint_error_dev(sc->sc.sc_dev, "couldn't create dmamap: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ti_sdhc_edma_xfer_data(struct sdhc_softc *sdhc_sc, struct sdmmc_command *cmd)
|
||||
{
|
||||
struct ti_sdhc_softc *sc = device_private(sdhc_sc->sc_dev);
|
||||
const bus_dmamap_t map = cmd->c_dmamap;
|
||||
int seg, error;
|
||||
bool bounce;
|
||||
|
||||
for (bounce = false, seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
|
||||
if ((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) != 0) {
|
||||
bounce = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bounce) {
|
||||
error = bus_dmamap_load(sc->sc.sc_dmat, sc->sc_edma_dmamap,
|
||||
sc->sc_edma_bbuf, MAXPHYS, NULL, BUS_DMA_WAITOK);
|
||||
if (error) {
|
||||
device_printf(sc->sc.sc_dev,
|
||||
"[bounce] bus_dmamap_load failed: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
|
||||
bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
|
||||
MAXPHYS, BUS_DMASYNC_PREREAD);
|
||||
} else {
|
||||
memcpy(sc->sc_edma_bbuf, cmd->c_data, cmd->c_datalen);
|
||||
bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
|
||||
MAXPHYS, BUS_DMASYNC_PREWRITE);
|
||||
}
|
||||
|
||||
cmd->c_dmamap = sc->sc_edma_dmamap;
|
||||
}
|
||||
|
||||
error = ti_sdhc_edma_transfer(sdhc_sc, cmd);
|
||||
|
||||
if (bounce) {
|
||||
if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
|
||||
bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
|
||||
MAXPHYS, BUS_DMASYNC_POSTREAD);
|
||||
} else {
|
||||
bus_dmamap_sync(sc->sc.sc_dmat, sc->sc_edma_dmamap, 0,
|
||||
MAXPHYS, BUS_DMASYNC_POSTWRITE);
|
||||
}
|
||||
bus_dmamap_unload(sc->sc.sc_dmat, sc->sc_edma_dmamap);
|
||||
if (ISSET(cmd->c_flags, SCF_CMD_READ) && error == 0) {
|
||||
memcpy(cmd->c_data, sc->sc_edma_bbuf, cmd->c_datalen);
|
||||
}
|
||||
|
||||
cmd->c_dmamap = map;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ti_sdhc_edma_transfer(struct sdhc_softc *sdhc_sc, struct sdmmc_command *cmd)
|
||||
{
|
||||
struct ti_sdhc_softc *sc = device_private(sdhc_sc->sc_dev);
|
||||
kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]);
|
||||
struct edma_channel *edma;
|
||||
uint16_t *edma_param;
|
||||
struct edma_param ep;
|
||||
size_t seg;
|
||||
int error, resid = cmd->c_datalen;
|
||||
int blksize = MIN(cmd->c_datalen, cmd->c_blklen);
|
||||
|
||||
KASSERT(mutex_owned(plock));
|
||||
|
||||
edma = ISSET(cmd->c_flags, SCF_CMD_READ) ?
|
||||
sc->sc_edma_rx : sc->sc_edma_tx;
|
||||
edma_param = ISSET(cmd->c_flags, SCF_CMD_READ) ?
|
||||
sc->sc_edma_param_rx : sc->sc_edma_param_tx;
|
||||
|
||||
DPRINTF(1, (sc->sc.sc_dev, "edma xfer: nsegs=%d ch# %d\n",
|
||||
cmd->c_dmamap->dm_nsegs, edma_channel_index(edma)));
|
||||
|
||||
if (cmd->c_dmamap->dm_nsegs > EDMA_MAX_PARAMS) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
|
||||
KASSERT(resid > 0);
|
||||
const int xferlen = uimin(resid,
|
||||
cmd->c_dmamap->dm_segs[seg].ds_len);
|
||||
KASSERT(xferlen == cmd->c_dmamap->dm_segs[seg].ds_len ||
|
||||
seg == cmd->c_dmamap->dm_nsegs - 1);
|
||||
resid -= xferlen;
|
||||
KASSERT((xferlen & 0x3) == 0);
|
||||
ep.ep_opt = __SHIFTIN(2, EDMA_PARAM_OPT_FWID) /* 32-bit */;
|
||||
ep.ep_opt |= __SHIFTIN(edma_channel_index(edma),
|
||||
EDMA_PARAM_OPT_TCC);
|
||||
if (seg == cmd->c_dmamap->dm_nsegs - 1) {
|
||||
ep.ep_opt |= EDMA_PARAM_OPT_TCINTEN;
|
||||
ep.ep_link = 0xffff;
|
||||
} else {
|
||||
ep.ep_link = EDMA_PARAM_BASE(edma_param[seg+1]);
|
||||
}
|
||||
if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
|
||||
ep.ep_opt |= EDMA_PARAM_OPT_SAM;
|
||||
ep.ep_src = sc->sc_edma_fifo;
|
||||
ep.ep_dst = cmd->c_dmamap->dm_segs[seg].ds_addr;
|
||||
} else {
|
||||
ep.ep_opt |= EDMA_PARAM_OPT_DAM;
|
||||
ep.ep_src = cmd->c_dmamap->dm_segs[seg].ds_addr;
|
||||
ep.ep_dst = sc->sc_edma_fifo;
|
||||
}
|
||||
|
||||
KASSERT(xferlen <= 65536 * 4);
|
||||
|
||||
/*
|
||||
* In constant addressing mode, the address must be aligned
|
||||
* to 256-bits.
|
||||
*/
|
||||
KASSERT((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) == 0);
|
||||
|
||||
/*
|
||||
* For unknown reason, the A-DMA transfers never completes for
|
||||
* transfers larger than 64 butes. So use a AB transfer,
|
||||
* with a 64 bytes A len
|
||||
*/
|
||||
ep.ep_bcntrld = 0; /* not used for AB-synchronous mode */
|
||||
ep.ep_opt |= EDMA_PARAM_OPT_SYNCDIM;
|
||||
ep.ep_acnt = uimin(xferlen, 64);
|
||||
ep.ep_bcnt = uimin(xferlen, blksize) / ep.ep_acnt;
|
||||
ep.ep_ccnt = xferlen / (ep.ep_acnt * ep.ep_bcnt);
|
||||
ep.ep_srcbidx = ep.ep_dstbidx = 0;
|
||||
ep.ep_srccidx = ep.ep_dstcidx = 0;
|
||||
if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
|
||||
ep.ep_dstbidx = ep.ep_acnt;
|
||||
ep.ep_dstcidx = ep.ep_acnt * ep.ep_bcnt;
|
||||
} else {
|
||||
ep.ep_srcbidx = ep.ep_acnt;
|
||||
ep.ep_srccidx = ep.ep_acnt * ep.ep_bcnt;
|
||||
}
|
||||
|
||||
edma_set_param(edma, edma_param[seg], &ep);
|
||||
#ifdef TISDHC_DEBUG
|
||||
if (tisdhcdebug >= 1) {
|
||||
printf("target OPT: %08x\n", ep.ep_opt);
|
||||
edma_dump_param(edma, edma_param[seg]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
error = 0;
|
||||
sc->sc_edma_pending = true;
|
||||
edma_transfer_enable(edma, edma_param[0]);
|
||||
while (sc->sc_edma_pending) {
|
||||
error = cv_timedwait(&sc->sc_edma_cv, plock, hz*10);
|
||||
if (error == EWOULDBLOCK) {
|
||||
device_printf(sc->sc.sc_dev, "transfer timeout!\n");
|
||||
edma_dump(edma);
|
||||
edma_dump_param(edma, edma_param[0]);
|
||||
edma_halt(edma);
|
||||
sc->sc_edma_pending = false;
|
||||
error = ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
edma_halt(edma);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static void
|
||||
ti_sdhc_edma_done(void *priv)
|
||||
{
|
||||
struct ti_sdhc_softc *sc = priv;
|
||||
kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]);
|
||||
|
||||
mutex_enter(plock);
|
||||
KASSERT(sc->sc_edma_pending == true);
|
||||
sc->sc_edma_pending = false;
|
||||
cv_broadcast(&sc->sc_edma_cv);
|
||||
mutex_exit(plock);
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/* $NetBSD: ti_sdhcreg.h,v 1.2.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
#ifndef _TI_SDMMCREG_H_
|
||||
#define _TI_SDMMCREG_H_
|
||||
|
||||
#define MMCHS_HL_REV 0x000
|
||||
#define MMCHS_HL_HWINFO 0x004
|
||||
# define HL_HWINFO_RETMODE (1 << 8)
|
||||
# define HL_HWINFO_MEM_SIZE_MASK (0xf << 2)
|
||||
# define HL_HWINFO_MEM_SIZE_512 (0x1 << 2)
|
||||
# define HL_HWINFO_MEM_SIZE_1024 (0x2 << 2)
|
||||
# define HL_HWINFO_MEM_SIZE_2048 (0x4 << 2)
|
||||
# define HL_HWINFO_MEM_SIZE_4096 (0x8 << 2)
|
||||
# define HL_HWINFO_MEMRGE_MEM (1 << 1)
|
||||
# define HL_HWINFO_MADMA_EN (1 << 0)
|
||||
#define MMCHS_HL_SYSCONFIG 0x010
|
||||
# define HL_SYSCONFIG_STANDBYMODE_MASK (0x3 << 2)
|
||||
# define HL_SYSCONFIG_STANDBYMODE_FORCE (0 << 2)
|
||||
# define HL_SYSCONFIG_STANDBYMODE_NO (1 << 2)
|
||||
# define HL_SYSCONFIG_STANDBYMODE_SMART (2 << 2)
|
||||
# define HL_SYSCONFIG_STANDBYMODE_WC (3 << 2) /* Smart-Idle wakeup-capable */
|
||||
# define HL_SYSCONFIG_IDLEMODE_MASK (0x3 << 2)
|
||||
# define HL_SYSCONFIG_IDLEMODE_FORCE (0 << 2)
|
||||
# define HL_SYSCONFIG_IDLEMODE_NO (1 << 2)
|
||||
# define HL_SYSCONFIG_IDLEMODE_SMART (2 << 2)
|
||||
# define HL_SYSCONFIG_IDLEMODE_WC (3 << 2) /* Smart-Idle wakeup-capable */
|
||||
# define HL_SYSCONFIG_FREEEMU (1 << 1)
|
||||
# define HL_SYSCONFIG_SOFTRESET (1 << 0)
|
||||
|
||||
#define MMCHS_SYSCONFIG 0x010 /* System Configuration */
|
||||
# define SYSCONFIG_CLOCKACTIVITY_MASK (3 << 8)
|
||||
# define SYSCONFIG_CLOCKACTIVITY_FCLK (2 << 8)
|
||||
# define SYSCONFIG_CLOCKACTIVITY_ICLK (1 << 8)
|
||||
# define SYSCONFIG_SIDLEMODE_MASK (3 << 3)
|
||||
# define SYSCONFIG_SIDLEMODE_AUTO (2 << 3)
|
||||
# define SYSCONFIG_SIDLEMODE_IGNORE (1 << 3)
|
||||
# define SYSCONFIG_ENAWAKEUP (1 << 2)
|
||||
# define SYSCONFIG_SOFTRESET (1 << 1)
|
||||
# define SYSCONFIG_AUTOIDLE (1 << 0)
|
||||
#define MMCHS_SYSSTATUS 0x014 /* System Status */
|
||||
# define SYSSTATUS_RESETDONE (1 << 0)
|
||||
#define MMCHS_CSRE 0x024 /* Card status response error */
|
||||
#define MMCHS_SYSTEST 0x028 /* System Test */
|
||||
#define MMCHS_CON 0x02c /* Configuration */
|
||||
# define CON_SDMA_LNE (1 << 21) /*Slave DMA Lvl/Edg Rq*/
|
||||
# define CON_MNS (1 << 20) /* DMA Mstr/Slv sel */
|
||||
# define CON_DDR (1 << 19) /* Dual Data Rate */
|
||||
# define CON_CF0 (1 << 18) /*Boot status support*/
|
||||
# define CON_BOOTACK (1 << 17) /*Boot acknowledge rcv*/
|
||||
# define CON_CLKEXTFREE (1 << 16)
|
||||
# define CON_PADEN (1 << 15) /* Ctrl Pow for MMC */
|
||||
# define CON_OBIE (1 << 14) /* Out-of-Band Intr */
|
||||
# define CON_OBIP (1 << 13) /*O-of-B Intr Polarity*/
|
||||
# define CON_CEATA (1 << 12) /* CE-ATA */
|
||||
# define CON_CTPL (1 << 11) /* Ctrl Power dat[1] */
|
||||
# define CON_DVAL_33US (0 << 9) /* debounce filter val*/
|
||||
# define CON_DVAL_231US (1 << 9) /* debounce filter val*/
|
||||
# define CON_DVAL_1MS (2 << 9) /* debounce filter val*/
|
||||
# define CON_DVAL_8_4MS (3 << 9) /* 8.4ms */
|
||||
# define CON_WPP (1 << 8) /* Write protect pol */
|
||||
# define CON_CDP (1 << 7) /*Card detect polarity*/
|
||||
# define CON_MIT (1 << 6) /* MMC interrupt cmd */
|
||||
# define CON_DW8 (1 << 5) /* 8-bit mode */
|
||||
# define CON_MODE (1 << 4) /* SYSTEST mode */
|
||||
# define CON_STR (1 << 3) /* Stream command */
|
||||
# define CON_HR (1 << 2) /* Broadcast host rsp */
|
||||
# define CON_INIT (1 << 1) /* Send init stream */
|
||||
# define CON_OD (1 << 0) /* Card open drain */
|
||||
#define MMCHS_PWCNT 0x030 /* Power counter */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,72 @@
|
|||
/* $NetBSD: ti_sysc.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: ti_sysc.c,v 1.1.2.2 2019/11/27 13:46:44 martin 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/kmem.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
static int ti_sysc_match(device_t, cfdata_t, void *);
|
||||
static void ti_sysc_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_sysc, 0, ti_sysc_match, ti_sysc_attach, NULL, NULL);
|
||||
|
||||
static const char * compatible[] = {
|
||||
"ti,sysc",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int
|
||||
ti_sysc_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
|
||||
ti_sysc_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal("\n");
|
||||
|
||||
fdt_add_bus(self, phandle, faa);
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/* $NetBSD: ti_tptc.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: ti_tptc.c,v 1.1.2.2 2019/11/27 13:46:44 martin 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/kmem.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
static int ti_tptc_match(device_t, cfdata_t, void *);
|
||||
static void ti_tptc_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_tptc, 0, ti_tptc_match, ti_tptc_attach, NULL, NULL);
|
||||
|
||||
static const char * compatible[] = {
|
||||
"ti,edma3-tptc",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int
|
||||
ti_tptc_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
|
||||
ti_tptc_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": EDMA Transfer Controller\n");
|
||||
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error_dev(self, "couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
/* $NetBSD: ti_usb.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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: ti_usb.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
#define UHH_SYSCONFIG 0x10
|
||||
#define UHH_SYSCONFIG_MIDLEMODE_MASK 0x00003000
|
||||
#define UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY 0x00002000
|
||||
#define UHH_SYSCONFIG_CLOCKACTIVITY 0x00000100
|
||||
#define UHH_SYSCONFIG_SIDLEMODE_MASK 0x00000018
|
||||
#define UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE 0x00000008
|
||||
#define UHH_SYSCONFIG_ENAWAKEUP 0x00000004
|
||||
#define UHH_SYSCONFIG_SOFTRESET 0x00000002
|
||||
#define UHH_SYSCONFIG_AUTOIDLE 0x00000001
|
||||
|
||||
#define UHH_HOSTCONFIG 0x40
|
||||
#define UHH_HOSTCONFIG_APP_START_CLK __BIT(31)
|
||||
#define UHH_HOSTCONFIG_P3_MODE __BITS(21,20)
|
||||
#define UHH_HOSTCONFIG_P2_MODE __BITS(19,18)
|
||||
#define UHH_HOSTCONFIG_P1_MODE __BITS(17,16)
|
||||
#define UHH_HOSTCONFIG_PMODE_ULPI_PHY 0
|
||||
#define UHH_HOSTCONFIG_PMODE_UTMI 1
|
||||
#define UHH_HOSTCONFIG_PMODE_HSIC 3
|
||||
#define UHH_HOSTCONFIG_P3_ULPI_BYPASS __BIT(12)
|
||||
#define UHH_HOSTCONFIG_P2_ULPI_BYPASS __BIT(11)
|
||||
#define UHH_HOSTCONFIG_P3_CONNECT_STATUS __BIT(10)
|
||||
#define UHH_HOSTCONFIG_P2_CONNECT_STATUS __BIT(9)
|
||||
#define UHH_HOSTCONFIG_P1_CONNECT_STATUS __BIT(8)
|
||||
#define UHH_HOSTCONFIG_ENA_INCR_ALIGN __BIT(5)
|
||||
#define UHH_HOSTCONFIG_ENA_INCR16 __BIT(4)
|
||||
#define UHH_HOSTCONFIG_ENA_INCR8 __BIT(3)
|
||||
#define UHH_HOSTCONFIG_ENA_INCR4 __BIT(2)
|
||||
#define UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN __BIT(1)
|
||||
#define UHH_HOSTCONFIG_P1_ULPI_BYPASS __BIT(0)
|
||||
|
||||
extern void tl_usbtll_enable_port(u_int);
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,usbhs-host",
|
||||
NULL
|
||||
};
|
||||
|
||||
#define TI_USB_NPORTS 3
|
||||
|
||||
enum {
|
||||
CONNECT_STATUS,
|
||||
ULPI_BYPASS,
|
||||
TI_USB_NBITS
|
||||
};
|
||||
|
||||
static const uint32_t ti_usb_portbits[TI_USB_NPORTS][TI_USB_NBITS] = {
|
||||
[0] = {
|
||||
[CONNECT_STATUS] = UHH_HOSTCONFIG_P1_CONNECT_STATUS,
|
||||
[ULPI_BYPASS] = UHH_HOSTCONFIG_P1_ULPI_BYPASS,
|
||||
},
|
||||
[1] = {
|
||||
[CONNECT_STATUS] = UHH_HOSTCONFIG_P2_CONNECT_STATUS,
|
||||
[ULPI_BYPASS] = UHH_HOSTCONFIG_P2_ULPI_BYPASS,
|
||||
},
|
||||
[2] = {
|
||||
[CONNECT_STATUS] = UHH_HOSTCONFIG_P3_CONNECT_STATUS,
|
||||
[ULPI_BYPASS] = UHH_HOSTCONFIG_P3_ULPI_BYPASS,
|
||||
},
|
||||
};
|
||||
|
||||
enum {
|
||||
PORT_UNUSED,
|
||||
PORT_EHCI_PHY,
|
||||
PORT_EHCI_TLL,
|
||||
PORT_EHCI_HSIC,
|
||||
};
|
||||
|
||||
struct ti_usb_softc {
|
||||
device_t sc_dev;
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
|
||||
u_int sc_portmode[TI_USB_NPORTS];
|
||||
};
|
||||
|
||||
static int ti_usb_match(device_t, cfdata_t, void *);
|
||||
static void ti_usb_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_usb, sizeof(struct ti_usb_softc),
|
||||
ti_usb_match, ti_usb_attach, NULL, NULL);
|
||||
|
||||
#define RD4(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
|
||||
#define WR4(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
|
||||
|
||||
static void
|
||||
ti_usb_init(struct ti_usb_softc *sc)
|
||||
{
|
||||
uint32_t val;
|
||||
int port;
|
||||
|
||||
val = RD4(sc, UHH_SYSCONFIG);
|
||||
val &= ~(UHH_SYSCONFIG_SIDLEMODE_MASK|UHH_SYSCONFIG_MIDLEMODE_MASK);
|
||||
val |= UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY;
|
||||
val |= UHH_SYSCONFIG_CLOCKACTIVITY;
|
||||
val |= UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE;
|
||||
val |= UHH_SYSCONFIG_ENAWAKEUP;
|
||||
val &= ~UHH_SYSCONFIG_AUTOIDLE;
|
||||
WR4(sc, UHH_SYSCONFIG, val);
|
||||
|
||||
val = RD4(sc, UHH_SYSCONFIG);
|
||||
|
||||
val = RD4(sc, UHH_HOSTCONFIG);
|
||||
val |= UHH_HOSTCONFIG_ENA_INCR16;
|
||||
val |= UHH_HOSTCONFIG_ENA_INCR8;
|
||||
val |= UHH_HOSTCONFIG_ENA_INCR4;
|
||||
val |= UHH_HOSTCONFIG_APP_START_CLK;
|
||||
val &= ~UHH_HOSTCONFIG_ENA_INCR_ALIGN;
|
||||
for (port = 0; port < TI_USB_NPORTS; port++) {
|
||||
if (sc->sc_portmode[port] == PORT_UNUSED)
|
||||
val &= ~ti_usb_portbits[port][CONNECT_STATUS];
|
||||
if (sc->sc_portmode[port] == PORT_EHCI_PHY)
|
||||
val &= ~ti_usb_portbits[port][ULPI_BYPASS];
|
||||
else
|
||||
val |= ti_usb_portbits[port][ULPI_BYPASS];
|
||||
}
|
||||
WR4(sc, UHH_HOSTCONFIG, val);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_usb_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_usb_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_usb_softc *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;
|
||||
char propname[16];
|
||||
const char *portmode;
|
||||
int port;
|
||||
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\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;
|
||||
}
|
||||
|
||||
for (port = 0; port < TI_USB_NPORTS; port++) {
|
||||
snprintf(propname, sizeof(propname), "port%d-mode", port + 1);
|
||||
portmode = fdtbus_get_string(phandle, propname);
|
||||
if (portmode == NULL)
|
||||
continue;
|
||||
if (strcmp(portmode, "ehci-phy") == 0)
|
||||
sc->sc_portmode[port] = PORT_EHCI_PHY;
|
||||
else if (strcmp(portmode, "ehci-tll") == 0)
|
||||
sc->sc_portmode[port] = PORT_EHCI_TLL;
|
||||
else if (strcmp(portmode, "ehci-hsic") == 0)
|
||||
sc->sc_portmode[port] = PORT_EHCI_HSIC;
|
||||
|
||||
if (sc->sc_portmode[port] != PORT_UNUSED)
|
||||
tl_usbtll_enable_port(port);
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": OMAP HS USB Host\n");
|
||||
|
||||
ti_usb_init(sc);
|
||||
|
||||
fdt_add_bus(self, phandle, faa);
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
/* $NetBSD: ti_usbtll.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* 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: ti_usbtll.c,v 1.1.2.2 2019/11/27 13:46:44 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
#define USBTLL_SYSCONFIG 0x10
|
||||
#define USBTLL_SYSCONFIG_CLOCKACTIVITY 0x00000100
|
||||
#define USBTLL_SYSCONFIG_SIDLEMODE 0x00000018
|
||||
#define USBTLL_SYSCONFIG_ENAWAKEUP 0x00000004
|
||||
#define USBTLL_SYSCONFIG_SOFTRESET 0x00000002
|
||||
#define USBTLL_SYSCONFIG_AUTOIDLE 0x00000001
|
||||
|
||||
#define USBTLL_SYSSTATUS 0x14
|
||||
#define USBTLL_SYSSTATUS_RESETDONE 0x00000001
|
||||
|
||||
#define USBTLL_SHARED_CONF 0x30
|
||||
#define USBTLL_SHARED_CONF_USB_90D_DDR_EN 0x00000040
|
||||
#define USBTLL_SHARED_CONF_USB_180D_SDR_EN 0x00000020
|
||||
#define USBTLL_SHARED_CONF_USB_DIVRATIO 0x0000001c
|
||||
#define USBTLL_SHARED_CONF_FCLK_REQ 0x00000002
|
||||
#define USBTLL_SHARED_CONF_FCLK_IS_ON 0x00000001
|
||||
|
||||
#define USBTLL_CHANNEL_CONF(i) (0x40 + (0x04 * (i)))
|
||||
#define USBTLL_CHANNEL_CONF_FSLSLINESTATE 0x30000000
|
||||
#define USBTLL_CHANNEL_CONF_FSLSMODE 0x0f000000
|
||||
#define USBTLL_CHANNEL_CONF_TESTTXSE0 0x00100000
|
||||
#define USBTLL_CHANNEL_CONF_TESTTXDAT 0x00080000
|
||||
#define USBTLL_CHANNEL_CONF_TESTTXEN 0x00040000
|
||||
#define USBTLL_CHANNEL_CONF_TESTEN 0x00020000
|
||||
#define USBTLL_CHANNEL_CONF_DRVVBUS 0x00010000
|
||||
#define USBTLL_CHANNEL_CONF_CHRGVBUS 0x00008000
|
||||
#define USBTLL_CHANNEL_CONF_ULPINOBITSTUFF 0x00000800
|
||||
#define USBTLL_CHANNEL_CONF_ULPIAUTOIDLE 0x00000400
|
||||
#define USBTLL_CHANNEL_CONF_UTMIAUTOIDLE 0x00000200
|
||||
#define USBTLL_CHANNEL_CONF_ULPIDDRMODE 0x00000100
|
||||
#define USBTLL_CHANNEL_CONF_ULPIOUTCLKMODE 0x00000080
|
||||
#define USBTLL_CHANNEL_CONF_TLLFULLSPEED 0x00000040
|
||||
#define USBTLL_CHANNEL_CONF_TLLCONNECT 0x00000020
|
||||
#define USBTLL_CHANNEL_CONF_TLLATTACH 0x00000010
|
||||
#define USBTLL_CHANNEL_CONF_UTMIISADEV 0x00000008
|
||||
#define USBTLL_CHANNEL_CONF_CHANMODE 0x00000006
|
||||
#define USBTLL_CHANNEL_CONF_CHANEN 0x00000001
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,usbhs-tll",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct ti_usbtll_softc {
|
||||
device_t sc_dev;
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
};
|
||||
|
||||
static int ti_usbtll_match(device_t, cfdata_t, void *);
|
||||
static void ti_usbtll_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_usbtll, sizeof(struct ti_usbtll_softc),
|
||||
ti_usbtll_match, ti_usbtll_attach, NULL, NULL);
|
||||
|
||||
#define RD4(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
|
||||
#define WR4(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
|
||||
|
||||
static struct ti_usbtll_softc *ti_usbtll_sc = NULL;
|
||||
|
||||
void tl_usbtll_enable_port(u_int);
|
||||
|
||||
void
|
||||
tl_usbtll_enable_port(u_int port)
|
||||
{
|
||||
struct ti_usbtll_softc *sc = ti_usbtll_sc;
|
||||
uint32_t val;
|
||||
|
||||
if (sc == NULL) {
|
||||
printf("%s: driver not loaded\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
val = RD4(sc, USBTLL_CHANNEL_CONF(port));
|
||||
val &= ~(USBTLL_CHANNEL_CONF_ULPINOBITSTUFF|
|
||||
USBTLL_CHANNEL_CONF_ULPIAUTOIDLE|
|
||||
USBTLL_CHANNEL_CONF_ULPIDDRMODE);
|
||||
val |= USBTLL_CHANNEL_CONF_CHANEN;
|
||||
WR4(sc, USBTLL_CHANNEL_CONF(port), val);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_usbtll_reset(struct ti_usbtll_softc *sc)
|
||||
{
|
||||
uint32_t val;
|
||||
int retry = 5000;
|
||||
|
||||
WR4(sc, USBTLL_SYSCONFIG, USBTLL_SYSCONFIG_SOFTRESET);
|
||||
do {
|
||||
val = RD4(sc, USBTLL_SYSSTATUS);
|
||||
if (val & USBTLL_SYSSTATUS_RESETDONE)
|
||||
break;
|
||||
delay(10);
|
||||
} while (--retry > 0);
|
||||
if (retry == 0)
|
||||
aprint_error_dev(sc->sc_dev, "reset timeout\n");
|
||||
}
|
||||
|
||||
static void
|
||||
ti_usbtll_init(struct ti_usbtll_softc *sc)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
ti_usbtll_reset(sc);
|
||||
|
||||
val = USBTLL_SYSCONFIG_ENAWAKEUP |
|
||||
USBTLL_SYSCONFIG_AUTOIDLE |
|
||||
USBTLL_SYSCONFIG_SIDLEMODE |
|
||||
USBTLL_SYSCONFIG_CLOCKACTIVITY;
|
||||
WR4(sc, USBTLL_SYSCONFIG, val);
|
||||
|
||||
val = RD4(sc, USBTLL_SHARED_CONF);
|
||||
val |= (USBTLL_SHARED_CONF_FCLK_IS_ON | (1 << 2));
|
||||
val &= ~USBTLL_SHARED_CONF_USB_90D_DDR_EN;
|
||||
val &= ~USBTLL_SHARED_CONF_USB_180D_SDR_EN;
|
||||
WR4(sc, USBTLL_SHARED_CONF, val);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_usbtll_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_usbtll_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_usbtll_softc *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;
|
||||
}
|
||||
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\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(": OMAP HS USB Host TLL\n");
|
||||
|
||||
ti_usbtll_init(sc);
|
||||
|
||||
if (ti_usbtll_sc == NULL)
|
||||
ti_usbtll_sc = sc;
|
||||
}
|
|
@ -1,174 +0,0 @@
|
|||
#
|
||||
# $NetBSD: BEAGLEBOARD,v 1.65 2019/02/06 11:58:30 rin Exp $
|
||||
#
|
||||
# BEAGLEBOARD -- TI OMAP 3530 Eval Board Kernel
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/std.beagle"
|
||||
include "arch/evbarm/conf/GENERIC.common"
|
||||
|
||||
# CPU options
|
||||
|
||||
#options UVMHIST,UVMHIST_PRINT
|
||||
options CPU_CORTEXA8
|
||||
options OMAP_3530
|
||||
|
||||
# Development and Debugging options
|
||||
|
||||
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
|
||||
|
||||
|
||||
# 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
|
||||
# pmapdebug=<n> If PMAP_DEBUG, set pmap_debug_level to <n>
|
||||
# memorydisk=<n> Set memorydisk size to <n> KB
|
||||
# quiet Show aprint_naive output
|
||||
# verbose Show aprint_normal and aprint_verbose output
|
||||
options BOOT_ARGS="\"\""
|
||||
|
||||
config netbsd root on ? type ?
|
||||
|
||||
# The main bus device
|
||||
mainbus0 at root
|
||||
|
||||
# The boot cpu
|
||||
cpu0 at mainbus?
|
||||
|
||||
# Specify the memory size in megabytes (optional).
|
||||
#options MEMSIZE=256
|
||||
#options MEMSIZE=128
|
||||
|
||||
# L3 Interconnect
|
||||
L3i0 at mainbus?
|
||||
|
||||
# OBIO
|
||||
obio0 at mainbus? base 0x48000000 size 0x1000000 # L4 CORE
|
||||
obio1 at mainbus? base 0x48300000 size 0x0100000 # L4 WAKEUP
|
||||
obio2 at mainbus? base 0x49000000 size 0x0100000 # L4 PERIPHERAL
|
||||
#obio3 at mainbus? base 0x54000000 size 0x0800000 # L4 EMUL
|
||||
|
||||
# General Purpose Memory Controller
|
||||
gpmc0 at mainbus? base 0x6e000000
|
||||
|
||||
# SDHC controllers
|
||||
sdhc0 at obio0 addr 0x4809C000 size 0x0400 intr 83
|
||||
#sdhc1 at obio0 addr 0x480B4000 size 0x0400 intr 86
|
||||
#sdhc2 at obio0 addr 0x480AD000 size 0x0400 intr 94
|
||||
sdmmc* at sdhc? # SD/MMC bus
|
||||
ld* at sdmmc?
|
||||
|
||||
|
||||
# NAND controller
|
||||
omapnand0 at gpmc? addr 0x30000000
|
||||
|
||||
# NAND layer
|
||||
nand0 at nandbus?
|
||||
|
||||
# use the bad block table
|
||||
options NAND_BBT
|
||||
|
||||
# Define flash partitions for board
|
||||
flash0 at nand0 offset 0x000000 size 0x080000 readonly 1 # X-Loader
|
||||
flash1 at nand0 offset 0x080000 size 0x1e0000 readonly 1 # U-Boot
|
||||
flash2 at nand0 offset 0x260000 size 0x020000 readonly 1 # UB Env
|
||||
flash3 at nand0 offset 0x280000 size 0x400000 # kernel
|
||||
flash4 at nand0 offset 0x680000 size 0 # filesystem
|
||||
|
||||
# Interrupt Controller
|
||||
omapicu0 at obio0 addr 0x48200000 size 0x1000 intrbase 0
|
||||
omapgpio0 at obio1 addr 0x48310000 size 0x0400 intrbase 96 intr 29
|
||||
#omapgpio1 at obio2 addr 0x49050000 size 0x0400 intrbase 128 intr 30
|
||||
#omapgpio2 at obio2 addr 0x49052000 size 0x0400 intrbase 160 intr 31
|
||||
#omapgpio3 at obio2 addr 0x49054000 size 0x0400 intrbase 192 intr 32
|
||||
omapgpio4 at obio2 addr 0x49056000 size 0x0400 intrbase 224 intr 33
|
||||
#omapgpio5 at obio2 addr 0x49058000 size 0x0400 intrbase 256 intr 34
|
||||
|
||||
gpio* at omapgpio?
|
||||
|
||||
# System Control Module
|
||||
omapscm0 at obio0 addr 0x48002000 size 0x1000
|
||||
|
||||
# I2C Controller
|
||||
omapiic0 at obio0 addr 0x48070000 size 0x80
|
||||
omapiic1 at obio0 addr 0x48072000 size 0x80
|
||||
omapiic2 at obio0 addr 0x48060000 size 0x80
|
||||
iic* at omapiic?
|
||||
|
||||
# Power Management and System Companion Device
|
||||
tps65950pm0 at iic0 addr 0x48
|
||||
tps65950pm1 at iic0 addr 0x49
|
||||
tps65950pm2 at iic0 addr 0x4a
|
||||
tps65950pm3 at iic0 addr 0x4b
|
||||
|
||||
# On-board 16550 UARTs
|
||||
com0 at obio2 addr 0x49020000 intr 74 mult 4 # UART3 (console)
|
||||
#options CONSADDR=0x49020000, CONSPEED=38400
|
||||
options CONSADDR=0x49020000, CONSPEED=115200
|
||||
|
||||
# Operating System Timer
|
||||
omapmputmr0 at obio2 addr 0x49032000 intr 38 # GP Timer 2
|
||||
# Statistics Timer
|
||||
omapmputmr1 at obio2 addr 0x49034000 intr 39 # GP Timer 3
|
||||
# Microtime Reference Timer
|
||||
omapmputmr2 at obio2 addr 0x49036000 intr 40 # GP Timer 4
|
||||
|
||||
# Watchdog timers
|
||||
#omapwdt32k* at obio2 addr 0x49030000 size 2048 # WDT3
|
||||
omapwdt32k* at obio1 addr 0x48314000 size 2048 # WDT2
|
||||
|
||||
# onboard DMA
|
||||
omapdma0 at obio0 addr 0x48056000 size 0x1000
|
||||
|
||||
# onboard video
|
||||
omapfb* at obio0 addr 0x48050000 size 0x10000
|
||||
wsdisplay* at wsemuldisplaydev? console ?
|
||||
|
||||
# various options for wscons - we try to look as much like a standard
|
||||
# sun console as possible
|
||||
options WSEMUL_VT100 # sun terminal emulation
|
||||
options WS_DEFAULT_FG=WSCOL_BLACK
|
||||
options WS_DEFAULT_BG=WSCOL_LIGHT_WHITE
|
||||
options WS_KERNEL_FG=WSCOL_GREEN
|
||||
options WS_KERNEL_BG=WSCOL_LIGHT_WHITE
|
||||
options WSDISPLAY_COMPAT_PCVT # emulate some ioctls
|
||||
options WSDISPLAY_COMPAT_SYSCONS # emulate some more ioctls
|
||||
options WSDISPLAY_COMPAT_USL # wsconscfg VT handling
|
||||
options WSDISPLAY_COMPAT_RAWKBD # can get raw scancodes
|
||||
options WSDISPLAY_DEFAULTSCREENS=4
|
||||
options FONT_QVSS8x15
|
||||
#options FONT_GALLANT12x22 # the console font
|
||||
|
||||
pseudo-device wsmux # mouse & keyboard multiplexor
|
||||
pseudo-device wsfont
|
||||
|
||||
# Power, Reset and Clock Management
|
||||
prcm* at obio1 addr 0x48306000 size 0x2000 # PRM Module
|
||||
|
||||
# On-board USB
|
||||
ehci* at obio0 addr 0x48064800 size 0x0400 intr 77
|
||||
usb* at ehci?
|
||||
|
||||
include "dev/usb/usbdevices.config"
|
||||
|
||||
midi* at midibus?
|
||||
|
||||
rgephy* at mii? phy ?
|
||||
rlphy* at mii? phy ?
|
||||
ukphy* at mii? phy ?
|
||||
|
||||
# Hardware clocking and power management
|
||||
|
||||
options HWCLOCK
|
||||
options HWCLOCK_MACHINE="<arch/arm/omap/hwclock_omap1.h>"
|
||||
options OMAP_CK_REF_SPEED=12000000
|
||||
|
||||
cinclude "arch/evbarm/conf/BEAGLEBOARD.local"
|
|
@ -1,156 +0,0 @@
|
|||
#
|
||||
# $NetBSD: BEAGLEBOARDXM,v 1.28 2018/10/23 19:58:52 jdolecek Exp $
|
||||
#
|
||||
# BEAGLEBOARD -- TI OMAP 3530 Eval Board Kernel
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/std.beagle"
|
||||
include "arch/evbarm/conf/GENERIC.common"
|
||||
|
||||
# CPU options
|
||||
|
||||
options CPU_CORTEXA8
|
||||
options TI_DM37XX
|
||||
|
||||
# Architecture options
|
||||
|
||||
# Development and Debugging options
|
||||
|
||||
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
|
||||
|
||||
|
||||
# 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
|
||||
# pmapdebug=<n> If PMAP_DEBUG, set pmap_debug_level to <n>
|
||||
# memorydisk=<n> Set memorydisk size to <n> KB
|
||||
# quiet Show aprint_naive output
|
||||
# verbose Show aprint_normal and aprint_verbose output
|
||||
options BOOT_ARGS="\"\""
|
||||
|
||||
config netbsd root on ? type ?
|
||||
|
||||
# The main bus device
|
||||
mainbus0 at root
|
||||
|
||||
# The boot cpu
|
||||
cpu0 at mainbus?
|
||||
|
||||
# Specify the memory size in megabytes.
|
||||
options MEMSIZE=512
|
||||
|
||||
# L3 Interconnect
|
||||
L3i0 at mainbus?
|
||||
|
||||
# OBIO
|
||||
obio0 at mainbus? base 0x48000000 size 0x1000000 # L4 CORE
|
||||
obio1 at mainbus? base 0x48300000 size 0x0100000 # L4 WAKEUP
|
||||
obio2 at mainbus? base 0x49000000 size 0x1000000 # L4 PERIPHERAL
|
||||
#obio3 at mainbus? base 0x54000000 size 0x0800000 # L4 EMUL
|
||||
|
||||
# General Purpose Memory Controller
|
||||
gpmc0 at mainbus? base 0x6e000000
|
||||
|
||||
# SDHC controllers
|
||||
#sdhc0 at obio0 addr 0x4809C000 size 0x0400 intr 83
|
||||
#sdhc1 at obio0 addr 0x480B4000 size 0x0400 intr 86
|
||||
#sdhc2 at obio0 addr 0x480AD000 size 0x0400 intr 94
|
||||
#sdmmc* at sdhc? # SD/MMC bus
|
||||
#ld* at sdmmc?
|
||||
|
||||
# Interrupt Controller
|
||||
omapicu0 at obio0 addr 0x48200000 size 0x1000 intrbase 0
|
||||
omapgpio0 at obio1 addr 0x48310000 size 0x0400 intrbase 96 intr 29
|
||||
#omapgpio1 at obio2 addr 0x49050000 size 0x0400 intrbase 128 intr 30
|
||||
#omapgpio2 at obio2 addr 0x49052000 size 0x0400 intrbase 160 intr 31
|
||||
#omapgpio3 at obio2 addr 0x49054000 size 0x0400 intrbase 192 intr 32
|
||||
omapgpio4 at obio2 addr 0x49056000 size 0x0400 intrbase 224 intr 33
|
||||
#omapgpio5 at obio2 addr 0x49058000 size 0x0400 intrbase 256 intr 34
|
||||
|
||||
gpio* at omapgpio?
|
||||
|
||||
# # I2C Controller
|
||||
# omapi2c0 at tipb? addr 0xfffb3800 intr 36 mult 4
|
||||
# iic* at omapi2c?
|
||||
# # omap's own i2c address
|
||||
# options OMAP_I2C_ADDRESS=0xe
|
||||
# # i2c bus clock low and high times in ns
|
||||
# options I2C_LOW_TIME_nSEC=1500
|
||||
# options I2C_HIGH_TIME_nSEC=1000
|
||||
|
||||
# On-board 16550 UARTs
|
||||
com0 at obio2 addr 0x49020000 intr 74 mult 4 # UART3 (console)
|
||||
#options CONSADDR=0x49020000, CONSPEED=38400
|
||||
options CONSADDR=0x49020000, CONSPEED=115200
|
||||
|
||||
# Operating System Timer
|
||||
omapmputmr0 at obio2 addr 0x49032000 intr 38 # GP Timer 2
|
||||
# Statistics Timer
|
||||
omapmputmr1 at obio2 addr 0x49034000 intr 39 # GP Timer 3
|
||||
# Microtime Reference Timer
|
||||
omapmputmr2 at obio2 addr 0x49036000 intr 40 # GP Timer 4
|
||||
options OMAP_MPU_TIMER_CLOCK_FREQ=12000000
|
||||
|
||||
# Watchdog timers
|
||||
omapwdt32k* at obio2 addr 0x49030000 size 2048 # WDT3
|
||||
#omapwdt32k* at obio1 addr 0x4830c000 size 2048 # WDT1
|
||||
#omapwdt32k* at obio1 addr 0x48314000 size 2048 # WDT2
|
||||
|
||||
# onboard video
|
||||
#omapfb* at obio0 addr 0x48050000 size 0x10000
|
||||
|
||||
# make sure the console display is always wsdisplay0
|
||||
#wsdisplay0 at wsemuldisplaydev? console 1
|
||||
#wsdisplay* at wsemuldisplaydev?
|
||||
|
||||
# various options for wscons - we try to look as much like a standard
|
||||
# sun console as possible
|
||||
#options WSEMUL_VT100 # sun terminal emulation
|
||||
#options WS_DEFAULT_FG=WSCOL_BLACK
|
||||
#options WS_DEFAULT_BG=WSCOL_LIGHT_WHITE
|
||||
#options WS_KERNEL_FG=WSCOL_GREEN
|
||||
#options WS_KERNEL_BG=WSCOL_LIGHT_WHITE
|
||||
#options WSDISPLAY_COMPAT_USL # wsconscfg VT handling
|
||||
#options WSDISPLAY_COMPAT_RAWKBD # can get raw scancodes
|
||||
#options WSDISPLAY_DEFAULTSCREENS=4
|
||||
#options FONT_QVSS8x15
|
||||
#options FONT_GALLANT12x22 # the console font
|
||||
|
||||
pseudo-device wsmux # mouse & keyboard multiplexor
|
||||
pseudo-device wsfont
|
||||
|
||||
# Power, Reset and Clock Management
|
||||
prcm* at obio1 addr 0x48306000 size 0x2000 # PRM Module
|
||||
|
||||
# On-board USB
|
||||
#ohci* at obio0 addr 0x48064400 size 0x0400 intr 76
|
||||
#ehci* at obio0 addr 0x48064800 size 0x0400 intr 77
|
||||
#usb* at ohci?
|
||||
#usb* at ehci?
|
||||
#uhub* at usb?
|
||||
#uhub* at uhub? port ?
|
||||
#umass* at uhub? port ? configuration ? interface ?
|
||||
#scsibus* at scsi?
|
||||
#sd* at scsibus? target ? lun ?
|
||||
#uhidev* at uhub?
|
||||
#ukbd* at uhidev?
|
||||
#ums* at uhidev?
|
||||
#wskbd* at ukbd?
|
||||
#wsmouse* at ums?
|
||||
|
||||
# USB Ethernet adapters
|
||||
#axe* at uhub? port ? configuration ? interface ?
|
||||
|
||||
# Hardware clocking and power management
|
||||
|
||||
options HWCLOCK
|
||||
options HWCLOCK_MACHINE="<arch/arm/omap/hwclock_omap1.h>"
|
||||
options OMAP_CK_REF_SPEED=12000000
|
|
@ -1,11 +0,0 @@
|
|||
# $NetBSD: BEAGLEBOARDXM_INSTALL,v 1.2 2014/05/01 18:43:45 martin Exp $
|
||||
#
|
||||
# BEAGLEBOARDXM_INSTALL -- BEAGLEBOARDXM kernel with installation-sized
|
||||
# ramdisk
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/BEAGLEBOARDXM"
|
||||
include "arch/evbarm/conf/INSTALL"
|
||||
|
||||
options BOOTHOWTO=RB_SINGLE
|
||||
no makeoptions DEBUG
|
|
@ -1,11 +0,0 @@
|
|||
# $NetBSD: BEAGLEBOARD_INSTALL,v 1.2 2014/05/01 18:43:45 martin Exp $
|
||||
#
|
||||
# BEAGLEBOARD_INSTALL -- BEAGLEBOARD kernel with installation-sized
|
||||
# ramdisk
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/BEAGLEBOARD"
|
||||
include "arch/evbarm/conf/INSTALL"
|
||||
|
||||
options BOOTHOWTO=RB_SINGLE
|
||||
no makeoptions DEBUG
|
|
@ -1,186 +0,0 @@
|
|||
#
|
||||
# $NetBSD: BEAGLEBONE,v 1.48 2019/05/18 08:49:23 skrll Exp $
|
||||
#
|
||||
# BEAGLEBONE -- TI AM335x board Kernel
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/std.beagle"
|
||||
include "arch/evbarm/conf/GENERIC.common"
|
||||
|
||||
# CPU options
|
||||
|
||||
options CPU_CORTEXA8
|
||||
options TI_AM335X
|
||||
|
||||
# XXX The Cortex PMC delay() doesn't seem to work.
|
||||
#no options CORTEX_PMC
|
||||
|
||||
# Architecture options
|
||||
#makeoptions CPUFLAGS+="-mthumb"
|
||||
|
||||
# Development and Debugging options
|
||||
|
||||
options DEBUG
|
||||
makeoptions DEBUG="-g" # compile full symbol table
|
||||
makeoptions COPY_SYMTAB=1
|
||||
|
||||
#options VERBOSE_INIT_ARM
|
||||
#options EARLYCONS=beagle # CONSADDR set below
|
||||
|
||||
## USB Debugging options
|
||||
options USB_DEBUG
|
||||
options EHCI_DEBUG
|
||||
options OHCI_DEBUG
|
||||
options UHUB_DEBUG
|
||||
|
||||
|
||||
# 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
|
||||
# pmapdebug=<n> If PMAP_DEBUG, set pmap_debug_level to <n>
|
||||
# memorydisk=<n> Set memorydisk size to <n> KB
|
||||
# quiet Show aprint_naive output
|
||||
# verbose Show aprint_normal and aprint_verbose output
|
||||
options BOOT_ARGS="\"-v\""
|
||||
|
||||
config netbsd root on ? type ?
|
||||
|
||||
# The main bus device
|
||||
mainbus0 at root
|
||||
|
||||
# The boot cpu
|
||||
cpu0 at mainbus?
|
||||
|
||||
# Specify the memory size in megabytes.
|
||||
#options MEMSIZE=256
|
||||
|
||||
# L3 Interconnect
|
||||
#L3i0 at mainbus?
|
||||
|
||||
# OBIO
|
||||
obio0 at mainbus? base 0x44c00000 size 0x00400000 # L4_WKUP
|
||||
obio1 at mainbus? base 0x48000000 size 0x01000000 # L4_PER
|
||||
obio2 at mainbus? base 0x4a000000 size 0x01000000 # L4_FAST
|
||||
|
||||
# Enhanced Direct Memory Access controller
|
||||
edma0 at mainbus? base 0x49000000 size 0x100000 intrbase 12
|
||||
|
||||
# General Purpose Memory Controller
|
||||
gpmc0 at mainbus? base 0x50000000
|
||||
|
||||
# Interrupt Controller
|
||||
omapicu0 at obio1 addr 0x48200000 size 0x1000 intrbase 0
|
||||
|
||||
# Power, Reset and Clock Management
|
||||
prcm0 at obio0 addr 0x44e00000 size 0x2000 # PRM Module
|
||||
|
||||
# Control Module
|
||||
sitaracm0 at obio0 addr 0x44e10000 size 0x2000
|
||||
|
||||
# SDHC controllers
|
||||
sdhc0 at obio1 addr 0x48060000 size 0x1000 intr 64 edmabase 24
|
||||
sdmmc0 at sdhc0
|
||||
ld0 at sdmmc0
|
||||
sdhc1 at obio1 addr 0x481d8000 size 0x1000 intr 28 edmabase 2 # BB Black
|
||||
sdmmc1 at sdhc1
|
||||
ld1 at sdmmc1
|
||||
#sdhc2 at obio0 addr 0x47810000 size 0x1000 intr 29
|
||||
#sdmmc2 at sdhc2
|
||||
#ld2 at sdmmc2
|
||||
sdmmc* at sdhc? # SD/MMC bus
|
||||
ld* at sdmmc?
|
||||
#options SDMMC_DEBUG
|
||||
#options SDHC_DEBUG
|
||||
|
||||
# General-purpose I/O pins
|
||||
omapgpio0 at obio0 addr 0x44e07000 size 0x1000 # intrbase 128 intr 29
|
||||
gpio0 at omapgpio0
|
||||
omapgpio1 at obio1 addr 0x4804c000 size 0x1000 # intrbase 160 intr 30
|
||||
gpio1 at omapgpio1
|
||||
omapgpio2 at obio1 addr 0x481ac000 size 0x1000 # intrbase 192 intr 32
|
||||
gpio2 at omapgpio2
|
||||
omapgpio3 at obio1 addr 0x481ae000 size 0x1000 # intrbase 224 intr 32
|
||||
gpio3 at omapgpio3
|
||||
gpio* at gpiobus?
|
||||
|
||||
# I2C Controller
|
||||
tiiic0 at obio0 addr 0x44e0b000 size 0x1000 intr 70
|
||||
iic* at tiiic?
|
||||
seeprom* at iic0 addr 0x50 flags 256 # 32768 bytes
|
||||
tps65217pmic* at iic0 addr 0x24
|
||||
|
||||
# On-board 16550 UARTs
|
||||
com0 at obio0 addr 0x44e09000 size 0x1000 intr 72 mult 4 # UART0
|
||||
options CONSADDR=0x44e09000, CONSPEED=115200
|
||||
|
||||
# XXX Clock assignment is kinda random. My DM timer 3 seems to be
|
||||
# unhappy and I don't know why. DM timer 0 doesn't seem to deliver
|
||||
# interrupts for the hard clock, although it seems to be the obvious
|
||||
# choice.
|
||||
|
||||
# Hardclock timer
|
||||
omapdmtimer0 at obio1 addr 0x48040000 size 0x1000 intr 68 # DM Timer 2
|
||||
|
||||
# Time counter
|
||||
omapdmtimer1 at obio0 addr 0x44e31000 size 0x1000 intr 67 # DM Timer 1ms
|
||||
|
||||
# Statclock timer
|
||||
omapdmtimer2 at obio1 addr 0x48044000 size 0x1000 intr 92 # DM Timer 4
|
||||
|
||||
# Watchdog timers
|
||||
omapwdt32k* at obio0 addr 0x44e35000 size 0x1000 # WDT1
|
||||
|
||||
# Random number generator
|
||||
trng* at obio1 addr 0x48310000 size 0x2000 intr 111 # TRNG
|
||||
|
||||
# onboard video, experimental. Video mode is hardcoded in the driver
|
||||
#tifb* at obio1 addr 0x4830E000 size 0x1000 intr 36
|
||||
|
||||
# make sure the console display is always wsdisplay0
|
||||
#wsdisplay* at wsemuldisplaydev?
|
||||
|
||||
# various options for wscons - we try to look as much like a standard
|
||||
# sun console as possible
|
||||
#options WSEMUL_VT100
|
||||
#options WSDISPLAY_COMPAT_PCVT
|
||||
#options WSDISPLAY_COMPAT_SYSCONS
|
||||
#options WSDISPLAY_COMPAT_USL
|
||||
#options WSDISPLAY_SCROLLSUPPORT
|
||||
#options WS_KERNEL_FG=WSCOL_GREEN
|
||||
#options WSDISPLAY_DEFAULTSCREENS=4
|
||||
#options FONT_GALLANT12x22
|
||||
#options FONT_BOLD8x16
|
||||
# compatibility to other console drivers
|
||||
#options WSDISPLAY_COMPAT_RAWKBD # can get raw scancodes
|
||||
|
||||
pseudo-device wsmux # mouse & keyboard multiplexor
|
||||
pseudo-device wsfont
|
||||
|
||||
# On-board USB. Experimental
|
||||
tiotg* at mainbus? base 0x47400000 size 0x5000 intrbase 17
|
||||
motg* at tiotg? port ?
|
||||
usb* at motg?
|
||||
|
||||
# USB device drivers
|
||||
include "dev/usb/usbdevices.config"
|
||||
|
||||
# needed for umidi
|
||||
midi* at midibus?
|
||||
|
||||
# SCSI bus support
|
||||
scsibus* at scsi?
|
||||
# SCSI devices
|
||||
sd* at scsibus? target ? lun ? # SCSI disk drives
|
||||
|
||||
# Ethernet
|
||||
cpsw* at obio2 addr 0x4a100000 size 0x8000 intrbase 40
|
||||
|
||||
rgephy* at mii? phy ?
|
||||
rlphy* at mii? phy ?
|
||||
ukphy* at mii? phy ?
|
||||
|
||||
# Pseudo-Devices
|
||||
|
||||
# local configuration
|
||||
cinclude "arch/evbarm/conf/BEAGLEBONE.local"
|
|
@ -1,11 +0,0 @@
|
|||
# $NetBSD: BEAGLEBONE_INSTALL,v 1.2 2014/05/01 18:43:45 martin Exp $
|
||||
#
|
||||
# BEAGLEBONE_INSTALL -- BEAGLEBONE kernel with installation-sized
|
||||
# ramdisk
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/BEAGLEBONE"
|
||||
include "arch/evbarm/conf/INSTALL"
|
||||
|
||||
options BOOTHOWTO=RB_SINGLE
|
||||
no makeoptions DEBUG
|
|
@ -1,15 +0,0 @@
|
|||
#
|
||||
# $NetBSD: DEVKIT8000,v 1.1 2010/09/08 22:53:53 ahoka Exp $
|
||||
#
|
||||
# DevKit8000 -- TI OMAP 3530 Eval Board Kernel
|
||||
#
|
||||
|
||||
# DevKit8000 is a Beagleboard clone
|
||||
#
|
||||
include "arch/evbarm/conf/BEAGLEBOARD"
|
||||
|
||||
include "arch/evbarm/conf/files.devkit8000"
|
||||
|
||||
# DM9000 Ethernet (requires omapgpio0)
|
||||
dme0 at gpmc? addr 0x2c000000 intr 121
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# $NetBSD: GENERIC,v 1.48.2.3 2019/10/17 18:47:47 martin Exp $
|
||||
# $NetBSD: GENERIC,v 1.48.2.4 2019/11/27 13:46:44 martin Exp $
|
||||
#
|
||||
# GENERIC ARM (aarch32) kernel
|
||||
#
|
||||
|
@ -12,10 +12,41 @@ include "arch/evbarm/conf/GENERIC.common"
|
|||
# FDT files supported by this kernel - add to DTSSUBDIR and DTS as
|
||||
# appropriate
|
||||
#
|
||||
makeoptions DTSARCH="arm aarch64"
|
||||
makeoptions DTSGNUARCH="arm arm64"
|
||||
makeoptions DTSSUBDIR="allwinner broadcom nvidia rockchip socfpga"
|
||||
makeoptions DTSARCH="arm"
|
||||
makeoptions DTSGNUARCH="arm"
|
||||
makeoptions DTSSUBDIR=""
|
||||
makeoptions DTS="
|
||||
am335x-baltos-ir2110.dts
|
||||
am335x-baltos-ir3220.dts
|
||||
am335x-baltos-ir5221.dts
|
||||
am335x-base0033.dts
|
||||
am335x-bone.dts
|
||||
am335x-boneblack-wireless.dts
|
||||
am335x-boneblack.dts
|
||||
am335x-boneblue.dts
|
||||
am335x-bonegreen-wireless.dts
|
||||
am335x-bonegreen.dts
|
||||
am335x-chiliboard.dts
|
||||
am335x-cm-t335.dts
|
||||
am335x-evm.dts
|
||||
am335x-evmsk.dts
|
||||
am335x-guardian.dts
|
||||
am335x-icev2.dts
|
||||
am335x-lxm.dts
|
||||
am335x-moxa-uc-2101.dts
|
||||
am335x-moxa-uc-8100-me-t.dts
|
||||
am335x-nano.dts
|
||||
am335x-osd3358-sm-red.dts
|
||||
am335x-pdu001.dts
|
||||
am335x-pepper.dts
|
||||
am335x-phycore-rdk.dts
|
||||
am335x-pocketbeagle.dts
|
||||
am335x-sancloud-bbe.dts
|
||||
am335x-sbc-t335.dts
|
||||
am335x-shc.dts
|
||||
am335x-sl50.dts
|
||||
am335x-wega-rdk.dts
|
||||
|
||||
bcm2836-rpi-2-b.dts
|
||||
bcm2837-rpi-3-a-plus.dts
|
||||
bcm2837-rpi-3-b.dts
|
||||
|
@ -31,6 +62,57 @@ makeoptions DTS="
|
|||
meson8b-mxq.dts
|
||||
meson8b-odroidc1.dts
|
||||
|
||||
omap3-beagle-xm-ab.dts
|
||||
omap3-beagle-xm.dts
|
||||
omap3-beagle.dts
|
||||
omap3-cm-t3517.dts
|
||||
omap3-cm-t3530.dts
|
||||
omap3-cm-t3730.dts
|
||||
omap3-devkit8000-lcd43.dts
|
||||
omap3-devkit8000-lcd70.dts
|
||||
omap3-devkit8000.dts
|
||||
omap3-evm-37xx.dts
|
||||
omap3-evm.dts
|
||||
omap3-gta04a3.dts
|
||||
omap3-gta04a4.dts
|
||||
omap3-gta04a5.dts
|
||||
omap3-gta04a5one.dts
|
||||
omap3-ha-lcd.dts
|
||||
omap3-ha.dts
|
||||
omap3-igep0020-rev-f.dts
|
||||
omap3-igep0020.dts
|
||||
omap3-igep0030-rev-g.dts
|
||||
omap3-igep0030.dts
|
||||
omap3-ldp.dts
|
||||
omap3-lilly-dbb056.dts
|
||||
omap3-n9.dts
|
||||
omap3-n900.dts
|
||||
omap3-n950.dts
|
||||
omap3-overo-alto35.dts
|
||||
omap3-overo-chestnut43.dts
|
||||
omap3-overo-gallop43.dts
|
||||
omap3-overo-palo35.dts
|
||||
omap3-overo-palo43.dts
|
||||
omap3-overo-storm-alto35.dts
|
||||
omap3-overo-storm-chestnut43.dts
|
||||
omap3-overo-storm-gallop43.dts
|
||||
omap3-overo-storm-palo35.dts
|
||||
omap3-overo-storm-palo43.dts
|
||||
omap3-overo-storm-summit.dts
|
||||
omap3-overo-storm-tobi.dts
|
||||
omap3-overo-storm-tobiduo.dts
|
||||
omap3-overo-summit.dts
|
||||
omap3-overo-tobi.dts
|
||||
omap3-overo-tobiduo.dts
|
||||
omap3-pandora-1ghz.dts
|
||||
omap3-pandora-600mhz.dts
|
||||
omap3-sbc-t3517.dts
|
||||
omap3-sbc-t3530.dts
|
||||
omap3-sbc-t3730.dts
|
||||
omap3-sniper.dts
|
||||
omap3-thunder.dts
|
||||
omap3-zoom3.dts
|
||||
|
||||
socfpga_cyclone5_de0_nano_soc.dts
|
||||
|
||||
sun4i-a10-a1000.dts
|
||||
|
@ -171,17 +253,13 @@ options CPU_CORTEXA8
|
|||
options CPU_CORTEXA9
|
||||
options CPU_CORTEXA15
|
||||
options CPU_CORTEXA17
|
||||
|
||||
options CPU_CORTEXA53
|
||||
|
||||
# Can't add SOC_BCM2835 until interrupt and register issues sorted out
|
||||
#options SOC_BCM2835
|
||||
options SOC_AM33XX
|
||||
options SOC_BCM2836
|
||||
|
||||
options SOC_EXYNOS5422
|
||||
|
||||
options SOC_MESON8B
|
||||
|
||||
options SOC_OMAP3
|
||||
options SOC_SUN4I_A10
|
||||
options SOC_SUN5I_A13
|
||||
options SOC_SUN6I_A31
|
||||
|
@ -189,11 +267,8 @@ options SOC_SUN7I_A20
|
|||
options SOC_SUN8I_A83T
|
||||
options SOC_SUN8I_H3
|
||||
options SOC_SUN9I_A80
|
||||
|
||||
options SOC_TEGRA124
|
||||
|
||||
options SOC_VIRT
|
||||
|
||||
options SOC_ZYNQ7000
|
||||
|
||||
options MULTIPROCESSOR
|
||||
|
@ -211,6 +286,9 @@ options MSGBUFSIZE=32768
|
|||
|
||||
# EARLYCONS is required for early init messages from VERBOSE_INIT_ARM.
|
||||
|
||||
#options EARLYCONS=am33xx, CONSADDR=0x44e09000
|
||||
#options EARLYCONS=omap3, CONSADDR=0x49020000
|
||||
|
||||
# ODROID-C1
|
||||
#options EARLYCONS=meson, CONSADDR=0xc81004c0
|
||||
|
||||
|
@ -258,12 +336,15 @@ cpufreqdt* at cpu?
|
|||
psci* at fdt?
|
||||
|
||||
# Clock and reset controllers
|
||||
am3prcm* at fdt? pass 1 # TI AM335x PRCM
|
||||
cycvclkmgr* at fdt? pass 1 # Cyclone V clock manager
|
||||
cycvrstmgr* at fdt? pass 0 # Cyclone V reset manager
|
||||
exy5410clk* at fdt? pass 3 # Exynos5410 clock controller
|
||||
exy5422clk* at fdt? pass 3 # Exynos5422 clock controller
|
||||
meson8bclkc* at fdt? pass 2 # Amlogic Meson8b clock controller
|
||||
mesonresets* at fdt? pass 2 # Amlogic Meson misc. clock resets
|
||||
omap3cm* at fdt? pass 1 # TI OMAP3 CM
|
||||
omap3prm* at fdt? pass 1 # TI OMAP3 PRM
|
||||
sun4ia10ccu* at fdt? pass 2 # Allwinner A10/A20 CCU
|
||||
sun5ia13ccu* at fdt? pass 2 # Allwinner A13 CCU
|
||||
sun6ia31ccu* at fdt? pass 2 # Allwinner A31 CCU
|
||||
|
@ -280,6 +361,9 @@ sun9immcclk* at fdt? pass 2 # Allwinner A80 SD/MMC-COMM
|
|||
sun9iusbclk* at fdt? pass 2 # Allwinner A80 USB HCI
|
||||
tegra124car* at fdt? pass 3 # NVIDIA Tegra CAR (T124)
|
||||
tegra210car* at fdt? pass 3 # NVIDIA Tegra CAR (T210)
|
||||
tidivclk* at fdt? pass 1 # TI divider clock
|
||||
tidpllclk* at fdt? pass 2 # TI DPLL clock
|
||||
timuxclk* at fdt? pass 1 # TI mux clock
|
||||
|
||||
fclock* at fdt? pass 1
|
||||
ffclock* at fdt? pass 1
|
||||
|
@ -297,6 +381,7 @@ sunxisramc* at fdt? pass 4 # SRAM controller
|
|||
|
||||
# System Controller
|
||||
syscon* at fdt? pass 1 # Generic System Controller
|
||||
tisysc* at fdt? pass 2 # TI sysc interconnect
|
||||
#zynqslcr* at fdt? pass 1 # Zynq 7000 system Controller
|
||||
|
||||
# Timer
|
||||
|
@ -308,6 +393,7 @@ gtmr* at fdt? pass 1 # ARM Generic Timer
|
|||
armgtmr0 at gtmr?
|
||||
mct* at fdt? pass 2 # Exynos Multi Core Timer (MCT)
|
||||
armgtmr* at mct?
|
||||
omaptimer* at fdt? # TI OMAP Timer
|
||||
sunxitimer* at fdt? # Allwinner async timer
|
||||
sunxihstimer* at fdt? # Allwinner High-Speed timer
|
||||
tegratimer* at fdt? # Timers
|
||||
|
@ -323,6 +409,7 @@ gic* at fdt? pass 1 # ARM GIC
|
|||
armgic0 at gic?
|
||||
bcmicu* at fdt? pass 1 # Broadcom BCM283x ICU
|
||||
exyointr* at fdt? pass 1 # Samsung Exynos ICU
|
||||
omapintc* at fdt? pass 2 # TI OMAP INTC
|
||||
tegralic* at fdt? pass 1 # NVIDIA Tegra LIC
|
||||
sunxiintc* at fdt? pass 1 # Allwinner INTC
|
||||
sunxinmi* at fdt? pass 2 # Allwinner NMI / R_INTC
|
||||
|
@ -333,6 +420,7 @@ arml2cc* at l2cc?
|
|||
|
||||
# Memory controller
|
||||
tegramc* at fdt? pass 4 # NVIDIA Tegra MC
|
||||
tigpmc* at fdt? pass 4 # TI OMAP2 GPMC
|
||||
|
||||
# Firmware devices
|
||||
bcmmbox* at fdt? # Broadcom VideoCore IV mailbox
|
||||
|
@ -344,6 +432,8 @@ bcmdmac* at fdt? # Broadcom BCM283x DMA controller
|
|||
sun4idma* at fdt? pass 4 # Allwinner DMA controller (sun4i)
|
||||
sun6idma* at fdt? pass 4 # Allwinner DMA controller (sun6i)
|
||||
tegraapbdma* at fdt? pass 4 # NVIDIA Tegra APB DMA
|
||||
tiedma* at fdt? pass 4 # TI EDMA3 (TPCC)
|
||||
titptc* at fdt? pass 3 # TI EDMA3 (TPTC)
|
||||
|
||||
# FUSE controller
|
||||
tegrafuse* at fdt? pass 4 # NVIDIA Tegra FUSE
|
||||
|
@ -366,9 +456,11 @@ mesonpinctrl* at fdt? pass 2 # Amlogic Meson GPIO
|
|||
plgpio* at fdt? # ARM PrimeCell GPIO
|
||||
sunxigpio* at fdt? pass 3 # Allwinner GPIO
|
||||
tegragpio* at fdt? pass 2 # NVIDIA Tegra GPIO
|
||||
tigpio* at fdt? pass 2 # TI GPIO
|
||||
gpio* at gpiobus?
|
||||
|
||||
# MPIO / Pinmux
|
||||
pinctrl* at fdt? pass 2 # Generic pinctrl driver
|
||||
tegrapinmux* at fdt? # NVIDIA Tegra MPIO
|
||||
|
||||
# PWM controller
|
||||
|
@ -396,6 +488,7 @@ pci* at ppb?
|
|||
# Ethernet
|
||||
awge* at fdt? # Allwinner Gigabit Ethernet (GMAC)
|
||||
cemac* at fdt? # Cadence EMAC/GEM ethernet controller
|
||||
cpsw* at fdt? # TI CPSW 3-port Ethernet Switch
|
||||
emac* at fdt? # Allwinner Fast/Gigabit Ethernet (EMAC)
|
||||
smsh* at fdt? # SMSC LAN9118
|
||||
|
||||
|
@ -447,6 +540,7 @@ exyoi2c* at fdt? # Samsung Exynos I2C
|
|||
sunxirsb* at fdt? pass 4 # Allwinner RSB
|
||||
sunxitwi* at fdt? # Allwinner TWI
|
||||
tegrai2c* at fdt? pass 4 # NVIDIA Tegra I2C
|
||||
tiiic* at fdt? pass 4 # TI OMAP I2C
|
||||
iic* at i2cbus?
|
||||
|
||||
# I2C devices
|
||||
|
@ -464,7 +558,11 @@ seeprom* at iic? # AT24Cxx Serial EEPROM
|
|||
sy8106a* at iic? # Silergy SY81061 regulator
|
||||
tcakp* at iic? # TI TCA8418 Keypad Scan IC
|
||||
tcagpio* at iic?
|
||||
tdahdmi* at iic? # NXP TDA19988 HDMI encoder
|
||||
titemp* at iic?
|
||||
tps65217pmic* at iic? # TI TPS65217 Power Management IC
|
||||
tps65217reg* at tps65217pmic?
|
||||
twl* at iic? # TI TWL4030 Power Management IC
|
||||
wskbd* at tcakp? console ?
|
||||
|
||||
# CAN bus
|
||||
|
@ -479,6 +577,7 @@ spi* at spibus?
|
|||
# Random number generators
|
||||
bcmrng* at fdt? # Broadcom BCM283x RNG
|
||||
mesonrng* at fdt? # Amlogic Meson RNG
|
||||
tirng* at fdt? # TI RNG
|
||||
|
||||
# Security ID EFUSE
|
||||
sunxisid* at fdt? pass 4 # SID
|
||||
|
@ -533,7 +632,8 @@ ld3 at sdmmc3
|
|||
ld* at sdmmc?
|
||||
|
||||
# NAND Flash
|
||||
sunxinand* at fdt? # NAND flash controller
|
||||
sunxinand* at fdt? # Allwinner NAND flash controller
|
||||
omapnand* at fdt? # TI OMAP2 flash controller
|
||||
nand* at nandbus?
|
||||
flash* at nand? dynamic 1
|
||||
|
||||
|
@ -562,6 +662,7 @@ hdmicec* at hdmicecbus?
|
|||
#tegrafb* at tegrafbbus?
|
||||
genfb* at fdt? # Simple Framebuffer
|
||||
mesonfb* at fdt? # Amlogic Meson Framebuffer
|
||||
omapfb* at fdt? # TI OMAP3 Framebuffer
|
||||
wsdisplay* at wsemuldisplaydev?
|
||||
sunxidebe* at fdt? pass 4 # Display Backend
|
||||
genfb* at sunxidebe?
|
||||
|
@ -571,6 +672,8 @@ connector* at fdt? pass 4
|
|||
panel* at fdt? pass 4
|
||||
#sunxidep must be after display pipeline elements but before genfb@fdt
|
||||
sunxidep* at fdt? pass 5 # Display Engine Pipeline
|
||||
tilcdc* at fdt? # TI OMAP4 LCDC
|
||||
tifb* at tilcdc?
|
||||
|
||||
options VCONS_DRAW_INTR
|
||||
options WSEMUL_VT100
|
||||
|
@ -615,6 +718,10 @@ sun9iusbphy* at fdt? pass 9 # Allwinner A80 USB PHY
|
|||
sunxiusbphy* at fdt? pass 9 # Allwinner USB PHY
|
||||
sunxiusb3phy* at fdt? pass 9 # Allwinner USB3 PHY
|
||||
tegrausbphy* at fdt? # NVIDIA Tegra USB PHY
|
||||
usbnopphy* at fdt? pass 9 # Generic USB PHY
|
||||
tiotg* at fdt? # TI dual port OTG
|
||||
tiusb* at fdt? pass 9 # TI HS USB host
|
||||
tiusbtll* at fdt? pass 8 # TI HS USB host TLL
|
||||
dwctwo* at fdt? # Designware USB DRD
|
||||
ehci* at fdt? # EHCI
|
||||
motg* at fdt? # Mentor Graphics USB OTG
|
||||
|
|
|
@ -1,268 +0,0 @@
|
|||
#
|
||||
# $NetBSD: IGEPV2,v 1.35.2.1 2019/11/21 18:17:59 martin Exp $
|
||||
#
|
||||
# IGEPv2 -- TI OMAP 3530 Eval Board Kernel
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/std.igepv2"
|
||||
|
||||
# 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_CORTEXA8
|
||||
options OMAP_3530
|
||||
options PMAPCOUNTERS
|
||||
|
||||
# Architecture options
|
||||
|
||||
# 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 SOFTDEP
|
||||
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
|
||||
|
||||
include "conf/compat_netbsd30.config"
|
||||
options COMPAT_NETBSD32 # allow running arm (e.g. non-earm) binaries
|
||||
|
||||
# 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
|
||||
|
||||
# Miscellaneous kernel options
|
||||
options KTRACE # system call tracing, a la ktrace(1)
|
||||
#options LKM # loadable kernel modules
|
||||
#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 DIAGNOSTIC # internal consistency checks
|
||||
#options DEBUG
|
||||
#options PMAP_DEBUG # Enable pmap_debug_level code
|
||||
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
|
||||
|
||||
options VERBOSE_INIT_ARM # verbose bootstraping messages
|
||||
options EARLYCONS=beagle
|
||||
options CONSADDR=0x49020000, CONSPEED=115200
|
||||
|
||||
## USB Debugging options
|
||||
#options USB_DEBUG
|
||||
#options OHCI_DEBUG
|
||||
#options UHUB_DEBUG
|
||||
|
||||
|
||||
# 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
|
||||
# pmapdebug=<n> If PMAP_DEBUG, set pmap_debug_level to <n>
|
||||
# memorydisk=<n> Set memorydisk size to <n> KB
|
||||
# quiet Show aprint_naive output
|
||||
# verbose Show aprint_normal and aprint_verbose output
|
||||
options BOOT_ARGS="\"\""
|
||||
|
||||
config netbsd root on ? type ?
|
||||
|
||||
# The main bus device
|
||||
mainbus0 at root
|
||||
|
||||
# The boot cpu
|
||||
cpu0 at mainbus?
|
||||
|
||||
# Specify the memory size in megabytes.
|
||||
options MEMSIZE=512
|
||||
|
||||
# L3 Interconnect
|
||||
L3i0 at mainbus?
|
||||
|
||||
# OBIO
|
||||
obio0 at mainbus? base 0x48000000 size 0x1000000 # L4 CORE
|
||||
obio1 at mainbus? base 0x48300000 size 0x0100000 # L4 WAKEUP
|
||||
obio2 at mainbus? base 0x49000000 size 0x0100000 # L4 PERIPHERAL
|
||||
#obio3 at mainbus? base 0x54000000 size 0x0800000 # L4 EMUL
|
||||
|
||||
# General Purpose Memory Controller
|
||||
gpmc0 at mainbus? base 0x6e000000
|
||||
|
||||
smsh0 at gpmc0 addr 0x2c000000 intr 272 # gpio5 16 (gpio 176)
|
||||
ukphy* at mii?
|
||||
|
||||
# SDHC controllers
|
||||
sdhc0 at obio0 addr 0x4809C000 size 0x0400 intr 83
|
||||
#sdhc1 at obio0 addr 0x480B4000 size 0x0400 intr 86
|
||||
#sdhc2 at obio0 addr 0x480AD000 size 0x0400 intr 94
|
||||
sdmmc* at sdhc? # SD/MMC bus
|
||||
ld* at sdmmc?
|
||||
|
||||
# NAND controller
|
||||
omapnand0 at gpmc? addr 0x20000000
|
||||
|
||||
# NAND layer
|
||||
nand0 at nandbus?
|
||||
|
||||
# use the bad block table
|
||||
options NAND_BBT
|
||||
|
||||
# Define flash partitions for board
|
||||
flash0 at nand0 offset 0x000000 size 0x080000 readonly 1 # X-Loader
|
||||
flash1 at nand0 offset 0x080000 size 0x1e0000 readonly 1 # U-Boot
|
||||
flash2 at nand0 offset 0x260000 size 0x020000 readonly 1 # UB Env
|
||||
flash3 at nand0 offset 0x280000 size 0x400000 # kernel
|
||||
flash4 at nand0 offset 0x680000 size 0 # filesystem
|
||||
|
||||
|
||||
# Interrupt Controller
|
||||
omapicu0 at obio0 addr 0x48200000 size 0x1000 intrbase 0
|
||||
omapgpio0 at obio1 addr 0x48310000 size 0x0400 intrbase 96 intr 29
|
||||
#omapgpio1 at obio2 addr 0x49050000 size 0x0400 intrbase 128 intr 30
|
||||
#omapgpio2 at obio2 addr 0x49052000 size 0x0400 intrbase 160 intr 31
|
||||
#omapgpio3 at obio2 addr 0x49054000 size 0x0400 intrbase 192 intr 32
|
||||
omapgpio4 at obio2 addr 0x49056000 size 0x0400 intrbase 224 intr 33
|
||||
omapgpio5 at obio2 addr 0x49058000 size 0x0400 intrbase 256 intr 34
|
||||
|
||||
gpio* at omapgpio?
|
||||
|
||||
# System Control Module
|
||||
omapscm0 at obio0 addr 0x48002000 size 0x1000
|
||||
|
||||
# I2C Controller
|
||||
omapiic0 at obio0 addr 0x48070000 size 0x1000 intr 56 # I2C1
|
||||
omapiic1 at obio0 addr 0x48060000 size 0x1000 intr 61 # I2C3
|
||||
iic* at omapiic?
|
||||
|
||||
# On-board 16550 UARTs
|
||||
#com0 at obio0 addr 0x4806a000 intr 72 mult 4 # UART1
|
||||
#com1 at obio0 addr 0x4806c000 intr 73 mult 4 # UART2
|
||||
com0 at obio2 addr 0x49020000 intr 74 mult 4 # UART3 (console)
|
||||
|
||||
# Operating System Timer
|
||||
omapmputmr0 at obio2 addr 0x49032000 intr 38 # GP Timer 2
|
||||
# Statistics Timer
|
||||
omapmputmr1 at obio2 addr 0x49034000 intr 39 # GP Timer 3
|
||||
# Microtime Reference Timer
|
||||
omapmputmr2 at obio2 addr 0x49036000 intr 40 # GP Timer 4
|
||||
options OMAP_MPU_TIMER_CLOCK_FREQ=12000000
|
||||
|
||||
# Watchdog timers
|
||||
omapwdt32k* at obio2 addr 0x49030000 size 2048 # WDT3
|
||||
#omapwdt32k* at obio1 addr 0x4830c000 size 2048 # WDT1
|
||||
#omapwdt32k* at obio1 addr 0x48314000 size 2048 # WDT2
|
||||
|
||||
# onboard DMA
|
||||
omapdma0 at obio0 addr 0x48056000 size 0x1000
|
||||
|
||||
# Power, Reset and Clock Management
|
||||
prcm* at obio1 addr 0x48306000 size 0x2000 # PRM Module
|
||||
|
||||
# On-board USB
|
||||
#ohci* at obio0 addr 0x48064400 size 0x0400 intr 76
|
||||
#ehci* at obio0 addr 0x48064800 size 0x0400 intr 77
|
||||
#usb* at ohci?
|
||||
#uhub* at usb?
|
||||
#umass* at uhub? port ? configuration ? interface ?
|
||||
#scsibus* at scsi?
|
||||
#sd* at scsibus ? target ? lun ?
|
||||
|
||||
# Hardware clocking and power management
|
||||
|
||||
options HWCLOCK
|
||||
options HWCLOCK_MACHINE="<arch/arm/omap/hwclock_omap1.h>"
|
||||
options OMAP_CK_REF_SPEED=12000000
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# $NetBSD: N900,v 1.31.2.1 2019/11/21 18:17:59 martin Exp $
|
||||
# $NetBSD: N900,v 1.31.2.2 2019/11/27 13:46:44 martin Exp $
|
||||
#
|
||||
# N900 -- Nokia N900 Kernel
|
||||
#
|
||||
|
@ -230,10 +230,7 @@ iic* at omapiic?
|
|||
|
||||
# I2C devices
|
||||
# Power Management and System Companion Device
|
||||
tps65950pm0 at iic0 addr 0x48
|
||||
tps65950pm1 at iic0 addr 0x49
|
||||
tps65950pm2 at iic0 addr 0x4a
|
||||
tps65950pm3 at iic0 addr 0x4b
|
||||
twl0 at iic0 addr 0x48
|
||||
|
||||
# On-board 16550 UARTs
|
||||
#com0 at obio2 addr 0x49020000 intr 74 mult 4 # UART3 (console)
|
||||
|
|
|
@ -1,359 +0,0 @@
|
|||
#
|
||||
# $NetBSD: OVERO,v 1.55 2019/04/26 22:46:03 sevan Exp $
|
||||
#
|
||||
# OVERO -- Gumstix. Inc. Overo COMS platforms kernel
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/std.overo"
|
||||
|
||||
#options INCLUDE_CONFIG_FILE # embed config file in kernel binary
|
||||
|
||||
# estimated number of users
|
||||
|
||||
maxusers 32
|
||||
|
||||
# CPU options
|
||||
|
||||
options CPU_CORTEXA8
|
||||
options OMAP_3530
|
||||
options FPU_VFP
|
||||
options PMAPCOUNTERS
|
||||
options ARM_HAS_VBAR
|
||||
options __HAVE_MM_MD_DIRECT_MAPPED_PHYS
|
||||
makeoptions CPUFLAGS="-mcpu=cortex-a8 -mfpu=neon"
|
||||
|
||||
# Architecture options
|
||||
|
||||
makeoptions BOARDTYPE="overo"
|
||||
options EVBARM_BOARDTYPE=overo
|
||||
|
||||
# Gumstix options
|
||||
options OVERO
|
||||
# Can specify 'expansion=' in args from u-boot.
|
||||
options GUMSTIX_NETBSD_ARGS_EXPANSION
|
||||
options GXIO_DEFAULT_EXPANSION="\"Chestnut43\""
|
||||
|
||||
# Standard system options
|
||||
|
||||
options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT
|
||||
#options NTP # NTP phase/frequency locked loop
|
||||
|
||||
# File systems
|
||||
|
||||
file-system FFS # UFS
|
||||
file-system EXT2FS # second extended file system (linux)
|
||||
#file-system LFS # log-structured file system
|
||||
file-system MFS # memory file system
|
||||
file-system NFS # Network file system
|
||||
#file-system NTFS # Windows/NT file system (experimental)
|
||||
#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 OVERLAY # overlay 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 CODA # Coda File System; also needs vcoda (below)
|
||||
#file-system SMBFS # experimental - CIFS; also needs nsmb (below)
|
||||
file-system TMPFS # memory file system
|
||||
file-system PTYFS # /dev/pts/N support
|
||||
#file-system UDF # experimental - OSTA UDF CD/DVD file-system
|
||||
#file-system HFS # experimental - Apple HFS+ (read-only)
|
||||
|
||||
# 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 WAPBL # File system journaling support
|
||||
#options UFS_DIRHASH # UFS Large Directory Hashing - Experimental
|
||||
#options NFSSERVER
|
||||
#options FFS_NO_SNAPSHOT # No FFS snapshot support
|
||||
#options EXT2FS_SYSTEM_FLAGS # makes ext2fs file flags (append and
|
||||
# immutable) behave as system flags.
|
||||
|
||||
# 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_BOOTPARAM
|
||||
|
||||
# Compatibility options
|
||||
|
||||
include "conf/compat_netbsd30.config"
|
||||
options COMPAT_NETBSD32 # allow running arm (e.g. non-earm) binaries
|
||||
|
||||
options COMPAT_OSSAUDIO # OSS (Voxware) audio driver compatibility
|
||||
options COMPAT_LINUX # binary compatibility with Linux
|
||||
|
||||
# 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_IS_ROOT # use memory disk as root
|
||||
#options MEMORY_DISK_DYNAMIC
|
||||
#options MEMORY_DISK_ROOT_SIZE=8192 # Size in blocks
|
||||
|
||||
# Miscellaneous kernel options
|
||||
options KTRACE # system call tracing, a la ktrace(1)
|
||||
options IRQSTATS # manage IRQ statistics
|
||||
#options MIIVERBOSE # verbose PHY autoconfig messages
|
||||
#options USBVERBOSE # verbose USB device autoconfig messages
|
||||
#options DDB_KEYCODE=0x40
|
||||
#options USERCONF # userconf(4) support
|
||||
#options PIPE_SOCKETPAIR # smaller, but slower pipe(2)
|
||||
#options SYSCTL_INCLUDE_DESCR # Include sysctl descriptions in kernel
|
||||
|
||||
# Development and Debugging options
|
||||
|
||||
options DIAGNOSTIC # internal consistency checks
|
||||
options DEBUG
|
||||
#options LOCKDEBUG
|
||||
#options PMAP_DEBUG # Enable pmap_debug_level code
|
||||
#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
|
||||
|
||||
config netbsd root on ? type ?
|
||||
|
||||
# The main bus device
|
||||
mainbus0 at root
|
||||
|
||||
# The boot cpu
|
||||
cpu0 at mainbus?
|
||||
|
||||
# L3 Interconnect
|
||||
L3i0 at mainbus?
|
||||
|
||||
# OBIO
|
||||
obio0 at mainbus? base 0x48000000 size 0x1000000 # L4 CORE
|
||||
obio1 at mainbus? base 0x48300000 size 0x0100000 # L4 WAKEUP
|
||||
obio2 at mainbus? base 0x49000000 size 0x0100000 # L4 PERIPHERAL
|
||||
#obio3 at mainbus? base 0x54000000 size 0x0800000 # L4 EMUL
|
||||
|
||||
# General Purpose Memory Controller
|
||||
gpmc0 at mainbus? base 0x6e000000
|
||||
|
||||
# Interrupt Controller
|
||||
omapicu0 at obio0 addr 0x48200000 size 0x1000 intrbase 0
|
||||
omapgpio0 at obio1 addr 0x48310000 size 0x1000 intrbase 96 intr 29
|
||||
omapgpio1 at obio2 addr 0x49050000 size 0x1000 intrbase 128 intr 30
|
||||
omapgpio2 at obio2 addr 0x49052000 size 0x1000 intrbase 160 intr 31
|
||||
omapgpio3 at obio2 addr 0x49054000 size 0x1000 intrbase 192 intr 32
|
||||
omapgpio4 at obio2 addr 0x49056000 size 0x1000 intrbase 224 intr 33
|
||||
omapgpio5 at obio2 addr 0x49058000 size 0x1000 intrbase 256 intr 34
|
||||
|
||||
gpio* at omapgpio?
|
||||
|
||||
# System Control Module
|
||||
omapscm0 at obio0 addr 0x48002000 size 0x1000
|
||||
|
||||
# I2C Controller
|
||||
omapiic0 at obio0 addr 0x48070000 size 0x1000 intr 56 # I2C1
|
||||
omapiic1 at obio0 addr 0x48060000 size 0x1000 intr 61 # I2C3
|
||||
iic* at omapiic?
|
||||
|
||||
# Power Management and System Companion Device
|
||||
tps65950pm0 at iic0 addr 0x48
|
||||
tps65950pm1 at iic0 addr 0x49
|
||||
tps65950pm2 at iic0 addr 0x4a
|
||||
tps65950pm3 at iic0 addr 0x4b
|
||||
|
||||
# On-board 16550 UARTs
|
||||
com0 at obio2 addr 0x49020000 intr 74 mult 4 # UART3 (console)
|
||||
options CONSADDR=0x49020000, CONSPEED=115200
|
||||
#com1 at obio0 addr 0x4806c000 intr 73 mult 4 # UART2 (bluetooth)
|
||||
com2 at obio0 addr 0x4806a000 intr 72 mult 4 # UART1 (Gallop's GPS)
|
||||
|
||||
# Operating System Timer
|
||||
omapmputmr0 at obio2 addr 0x49032000 intr 38 # GP Timer 2
|
||||
# Statistics Timer
|
||||
omapmputmr1 at obio2 addr 0x49034000 intr 39 # GP Timer 3
|
||||
# Microtime Reference Timer
|
||||
omapmputmr2 at obio2 addr 0x49036000 intr 40 # GP Timer 4
|
||||
options OMAP_MPU_TIMER_CLOCK_FREQ=13000000
|
||||
|
||||
# Watchdog timers
|
||||
omapwdt32k* at obio1 addr 0x48314000 size 0x1000 # WDT2
|
||||
#omapwdt32k* at obio2 addr 0x49030000 size 0x1000 # WDT3
|
||||
|
||||
# onboard DMA
|
||||
omapdma0 at obio0 addr 0x48056000 size 0x1000
|
||||
|
||||
# Power, Reset and Clock Management
|
||||
prcm* at obio1 addr 0x48306000 size 0x2000 # PRM Module
|
||||
|
||||
# SDHC controllers
|
||||
sdhc0 at obio0 addr 0x4809c000 size 0x1000 intr 83
|
||||
sdhc1 at obio0 addr 0x480b4000 size 0x1000 intr 86 # Wifi
|
||||
|
||||
sdmmc* at sdhc? # SD/MMC bus
|
||||
ld* at sdmmc?
|
||||
|
||||
# NAND controller
|
||||
omapnand0 at gpmc? cs 0
|
||||
|
||||
# NAND layer
|
||||
nand0 at nandbus?
|
||||
|
||||
# use the bad block table
|
||||
options NAND_BBT
|
||||
|
||||
# Define flash partitions for board
|
||||
flash0 at nand0 offset 0x000000 size 0x080000 readonly 1 # SPL
|
||||
flash1 at nand0 offset 0x080000 size 0x1c0000 readonly 1 # U-Boot
|
||||
flash2 at nand0 offset 0x240000 size 0x040000 readonly 1 # Environment
|
||||
flash3 at nand0 offset 0x280000 size 0x800000 # Kernel
|
||||
flash4 at nand0 offset 0xa80000 size 0 # Filesystem
|
||||
|
||||
# Hardware clocking and power management
|
||||
|
||||
options HWCLOCK
|
||||
options HWCLOCK_MACHINE="<arch/arm/omap/hwclock_omap1.h>"
|
||||
options OMAP_CK_REF_SPEED=12000000
|
||||
|
||||
# overo expansion boards
|
||||
|
||||
# SMSC LAN9221
|
||||
smsh0 at gpmc? cs 5 intr 272 # Tobi, Chestnut43
|
||||
smsh1 at gpmc? cs 4 intr 161 # Tobi-Duo
|
||||
|
||||
# MII/PHY support
|
||||
ukphy* at mii? phy ? # smsh(4) internal PHY
|
||||
|
||||
# LCD/DVI-D
|
||||
#omapfb* at obio0 addr 0x48050000 size 0x1000 # Chestnut*, Palo*,
|
||||
# Gallop* (LCD)
|
||||
# Tobi, Summit (DVI-D)
|
||||
|
||||
# make sure the console display is always wsdisplay0
|
||||
#wsdisplay* at wsemuldisplaydev? console ?
|
||||
|
||||
# various options for wscons - we try to look as much like a standard
|
||||
# sun console as possible
|
||||
#options WSEMUL_VT100 # sun terminal emulation
|
||||
#options WS_DEFAULT_FG=WSCOL_BLACK
|
||||
#options WS_DEFAULT_BG=WSCOL_LIGHT_WHITE
|
||||
#options WS_KERNEL_FG=WSCOL_GREEN
|
||||
#options WS_KERNEL_BG=WSCOL_LIGHT_WHITE
|
||||
#options WSDISPLAY_COMPAT_USL # VT handling
|
||||
#options WSDISPLAY_COMPAT_RAWKBD # can get raw scancodes
|
||||
#options WSDISPLAY_DEFAULTSCREENS=4
|
||||
#options FONT_QVSS8x15
|
||||
#options FONT_GALLANT12x22 # the console font
|
||||
|
||||
# USB Host
|
||||
ehci* at obio0 addr 0x48064800 size 0x1000 intr 77
|
||||
# Chestnut*, Palo*,
|
||||
# RoboVero, Summit,
|
||||
# Tobi, TurtleCore
|
||||
usb* at ehci?
|
||||
|
||||
# USB Hubs
|
||||
uhub* at usb?
|
||||
uhub* at uhub? port ?
|
||||
|
||||
umass* at uhub? port ?
|
||||
scsibus* at scsi?
|
||||
sd* at scsibus? target ? lun ?
|
||||
|
||||
# Pseudo-Devices
|
||||
|
||||
# disk/mass storage pseudo-devices
|
||||
#pseudo-device bio # RAID control device driver
|
||||
#pseudo-device ccd # concatenated/striped disk devices
|
||||
pseudo-device cgd # cryptographic disk devices
|
||||
#pseudo-device raid # RAIDframe disk driver
|
||||
#options RAID_AUTOCONFIG # auto-configuration of RAID components
|
||||
# Options to enable various other RAIDframe RAID types.
|
||||
#options RF_INCLUDE_EVENODD=1
|
||||
#options RF_INCLUDE_RAID5_RS=1
|
||||
#options RF_INCLUDE_PARITYLOGGING=1
|
||||
#options RF_INCLUDE_CHAINDECLUSTER=1
|
||||
#options RF_INCLUDE_INTERDECLUSTER=1
|
||||
#options RF_INCLUDE_PARITY_DECLUSTERING=1
|
||||
#options RF_INCLUDE_PARITY_DECLUSTERING_DS=1
|
||||
#pseudo-device fss # file system snapshot device
|
||||
|
||||
#pseudo-device md # memory disk device (ramdisk)
|
||||
pseudo-device vnd # disk-like interface to files
|
||||
options VND_COMPRESSION # compressed vnd(4)
|
||||
#pseudo-device putter # for puffs and pud
|
||||
|
||||
# network pseudo-devices
|
||||
pseudo-device bpfilter # Berkeley packet filter
|
||||
#pseudo-device carp # Common Address Redundancy Protocol
|
||||
pseudo-device npf # NPF packet filter
|
||||
pseudo-device loop # network loopback
|
||||
#pseudo-device ppp # Point-to-Point Protocol
|
||||
#pseudo-device pppoe # PPP over Ethernet (RFC 2516)
|
||||
#pseudo-device sl # Serial Line IP
|
||||
#pseudo-device strip # Starmode Radio IP (Metricom)
|
||||
#pseudo-device irframetty # IrDA frame line discipline
|
||||
pseudo-device tap # virtual Ethernet
|
||||
#pseudo-device tun # network tunneling over tty
|
||||
#pseudo-device gre # generic L3 over IP tunnel
|
||||
#pseudo-device gif # IPv[46] over IPv[46] tunnel (RFC 1933)
|
||||
#pseudo-device faith # IPv[46] TCP relay translation i/f
|
||||
#pseudo-device stf # 6to4 IPv6 over IPv4 encapsulation
|
||||
#pseudo-device vlan # IEEE 802.1q encapsulation
|
||||
pseudo-device bridge # simple inter-network bridging
|
||||
#options BRIDGE_IPF # bridge uses IP/IPv6 pfil hooks too
|
||||
#pseudo-device agr # IEEE 802.3ad link aggregation
|
||||
|
||||
# miscellaneous pseudo-devices
|
||||
pseudo-device pty # pseudo-terminals
|
||||
#pseudo-device sequencer # MIDI sequencer
|
||||
options RND_COM
|
||||
pseudo-device clockctl # user control of clock subsystem
|
||||
pseudo-device ksyms # /dev/ksyms
|
||||
#pseudo-device btuart # Bluetooth HCI UART (H4)
|
||||
# CSR or WiLink 8 module
|
||||
|
||||
# a pseudo device needed for Coda # also needs CODA (above)
|
||||
#pseudo-device vcoda # coda minicache <-> venus comm.
|
||||
|
||||
# a pseudo device needed for SMBFS
|
||||
#pseudo-device nsmb # experimental - SMB requester
|
||||
|
||||
# wscons pseudo-devices
|
||||
pseudo-device wsmux # mouse & keyboard multiplexor
|
||||
pseudo-device wsfont
|
||||
|
||||
# data mover pseudo-devices
|
||||
#pseudo-device swdmover # software dmover(9) back-end
|
||||
#pseudo-device dmoverio # /dev/dmover dmover(9) interface
|
||||
|
||||
# userland interface to drivers, including autoconf and properties retrieval
|
||||
pseudo-device drvctl
|
||||
|
||||
# Veriexec
|
||||
# include "dev/veriexec.config"
|
||||
|
||||
#options PAX_MPROTECT=0 # PaX mprotect(2) restrictions
|
||||
#options PAX_ASLR=0 # PaX Address Space Layout Randomization
|
|
@ -1,10 +0,0 @@
|
|||
# $NetBSD: OVERO_INSTALL,v 1.1 2015/02/27 13:18:11 kiyohara Exp $
|
||||
#
|
||||
# OVERO_INSTALL -- OVERO kernel with installation-sized ramdisk
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/OVERO"
|
||||
include "arch/evbarm/conf/INSTALL"
|
||||
|
||||
options BOOTHOWTO=RB_SINGLE
|
||||
no makeoptions DEBUG
|
|
@ -1,4 +1,4 @@
|
|||
$NetBSD: README.evbarm,v 1.21 2019/03/31 13:04:54 jmcneill Exp $
|
||||
$NetBSD: README.evbarm,v 1.21.4.1 2019/11/27 13:46:44 martin Exp $
|
||||
|
||||
config date boards
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -6,19 +6,14 @@ ADI_BRH 2003/01/25 ADI Eng. Big Read Head i80200 eval board
|
|||
ARMADILLO210 2006/02/06 Atmark Techno Armadillo-210
|
||||
ARMADILLO9 2005/11/13 Atmark Techno Armadillo-9
|
||||
BCM5301X 2012/08/31 Broadcom BCM95301X evaluation/reference board
|
||||
BEAGLEBOARD 2008/10/22 TI OMAP3530 BeagleBoard
|
||||
BEAGLEBOARDXM 2008/08/20 TI DM37xx BeagleBoard-XM
|
||||
BEAGLEBONE 2012/08/20 TI AM335x BeagleBone
|
||||
CUBOX 2017/01/07 SolidRun Cubox
|
||||
CP3100 2006/11/08 Certance IOP321 CP-3100
|
||||
DEVKIT8000 2010/09/08 Embest OMAP3530 DevKit8000 eval Kit
|
||||
DNS323 2010/10/02 D-Link DNS-323 Marvell SoC based NAS
|
||||
DUOVERO 2016/10/15 Gumstix Inc. DuoVero COMS boards
|
||||
GEMINI 2008/10/24 Cortina Systems SL3516 eval board
|
||||
GUMSTIX 2006/10/16 Gumstix Inc. PXA255/270 based boards
|
||||
HDL_G 2006/04/16 I-O DATA HDL-G Giga LANDISK
|
||||
HPT5325 2012/03/31 HP t5325 Thin Client
|
||||
IGEPV2 2010/06/16 IGEPv2 OMAP3530 eval board
|
||||
IMX31LITE 2008/04/27 Freescale i.M31 DEV LITE KIT
|
||||
INTEGRATOR 2001/10/27 ARM Integrator board
|
||||
IQ31244 2003/05/14 Intel IQ31244 reference board
|
||||
|
@ -43,7 +38,6 @@ OPENBLOCKS_A6 2012/08/01 Plat'Home. OpenBlockS A6
|
|||
OPENBLOCKS_AX3 2013/09/30 Plat'Home. OpenBlockS AX3
|
||||
OPENRD 2012/08/10 open-rd.org Marvell Orion board
|
||||
OSK5912 2007/01/06 TI OMAP 5912 OSK board
|
||||
OVERO 2010/07/10 Gumstix Inc. Overo COMS boards
|
||||
PANDABOARD 2012/08/20 TI OMAP4430 PandaBoard
|
||||
PARALLELLA 2015/01/23 Xilinx Zynq and Epiphany multi-core chips
|
||||
PEPPER 2016/10/15 Gumstix Inc. Pepper SBC(Single Board Computer)
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
# $NetBSD: TI,v 1.6 2018/11/21 08:37:06 skrll Exp $
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/std.ti"
|
||||
include "arch/evbarm/conf/GENERIC.common"
|
||||
|
||||
options VERBOSE_INIT_ARM
|
||||
options CONSADDR=0x44e09000
|
||||
|
||||
makeoptions DTS="
|
||||
am335x-bone.dts
|
||||
am335x-boneblack.dts
|
||||
am335x-boneblack-wireless.dts
|
||||
am335x-bonegreen.dts
|
||||
am335x-bonegreen-wireless.dts
|
||||
"
|
||||
|
||||
makeoptions DEBUG="-g" # compile full symbol table
|
||||
makeoptions COPY_SYMTAB=1
|
||||
|
||||
#options DIAGNOSTIC
|
||||
#options DEBUG
|
||||
options LOCKDEBUG
|
||||
|
||||
options CPU_CORTEXA8
|
||||
|
||||
options OMAP_SYSTEM_CLOCK_FREQ="48000000UL"
|
||||
|
||||
config netbsd root on ? type ?
|
||||
|
||||
armfdt0 at root
|
||||
simplebus* at fdt? pass 0
|
||||
|
||||
cpus* at fdt? pass 0
|
||||
cpu* at fdt? pass 0
|
||||
|
||||
am3prcm* at fdt? pass 1
|
||||
|
||||
com* at fdt?
|
||||
|
||||
omapintc* at fdt? pass 2
|
||||
omaptimer* at fdt?
|
||||
|
||||
fregulator* at fdt?
|
||||
gpioleds* at fdt?
|
||||
|
||||
cpsw* at fdt?
|
||||
ukphy* at mii?
|
||||
|
||||
cinclude "arch/evbarm/conf/TI.local"
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.generic,v 1.7.2.1 2019/09/17 19:54:10 martin Exp $
|
||||
# $NetBSD: files.generic,v 1.7.2.2 2019/11/27 13:46:44 martin Exp $
|
||||
#
|
||||
# A generic (aarch32) kernel configuration info
|
||||
#
|
||||
|
@ -23,6 +23,7 @@ include "arch/arm/broadcom/files.bcm2835"
|
|||
include "arch/arm/nvidia/files.tegra"
|
||||
include "arch/arm/samsung/files.exynos"
|
||||
include "arch/arm/sunxi/files.sunxi"
|
||||
include "arch/arm/ti/files.ti"
|
||||
include "arch/arm/vexpress/files.vexpress"
|
||||
include "arch/arm/virt/files.virt"
|
||||
include "arch/arm/xilinx/files.zynq"
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
# $NetBSD: files.ti,v 1.2 2018/11/21 08:55:05 skrll Exp $
|
||||
#
|
||||
|
||||
include "arch/arm/pic/files.pic"
|
||||
include "arch/arm/cortex/files.cortex"
|
||||
|
||||
include "arch/evbarm/conf/files.fdt"
|
||||
|
||||
include "arch/arm/ti/files.ti"
|
|
@ -1,28 +0,0 @@
|
|||
# $NetBSD: std.igepv2,v 1.10 2018/10/15 16:54:54 skrll Exp $
|
||||
#
|
||||
# standard NetBSD/evbarm for IGEPV2 options
|
||||
|
||||
machine evbarm arm
|
||||
include "arch/evbarm/conf/std.evbarm"
|
||||
|
||||
# Pull in BEAGLEBOARD config definitions.
|
||||
include "arch/evbarm/conf/files.beagle"
|
||||
|
||||
options KDTRACE_HOOKS
|
||||
options MODULAR
|
||||
options MODULAR_DEFAULT_AUTOLOAD
|
||||
options CORTEX_PMC
|
||||
options __HAVE_CPU_COUNTER
|
||||
options __HAVE_FAST_SOFTINTS # should be in types.h
|
||||
options __HAVE_CPU_UAREA_ALLOC_IDLELWP
|
||||
options __HAVE_MM_MD_DIRECT_MAPPED_PHYS
|
||||
options ARM_HAS_VBAR
|
||||
options FPU_VFP
|
||||
options TPIDRPRW_IS_CURCPU
|
||||
|
||||
makeoptions LOADADDRESS="0x80300000"
|
||||
makeoptions BOARDTYPE="igepv2"
|
||||
makeoptions BOARDMKFRAG="${THISARM}/conf/mk.beagle"
|
||||
|
||||
options ARM_INTR_IMPL="<arch/arm/omap/omap2_intr.h>"
|
||||
options ARM_GENERIC_TODR
|
|
@ -1,30 +0,0 @@
|
|||
# $NetBSD: std.ti,v 1.5 2018/11/21 08:55:05 skrll Exp $
|
||||
#
|
||||
|
||||
machine evbarm arm
|
||||
include "arch/evbarm/conf/std.evbarm"
|
||||
|
||||
include "arch/evbarm/conf/files.ti"
|
||||
|
||||
options ARM_GENERIC_TODR
|
||||
options ARM_HAS_VBAR
|
||||
options ARM_INTR_IMPL="<arch/arm/fdt/fdt_intr.h>"
|
||||
options DRAM_BLOCKS=256
|
||||
options FDT
|
||||
options FPU_VFP
|
||||
options TPIDRPRW_IS_CURCPU
|
||||
options __BUS_SPACE_HAS_STREAM_METHODS
|
||||
options __HAVE_CPU_COUNTER
|
||||
options __HAVE_CPU_UAREA_ALLOC_IDLELWP
|
||||
options __HAVE_FAST_SOFTINTS
|
||||
options __HAVE_GENERIC_CPU_INITCLOCKS
|
||||
options __HAVE_GENERIC_START
|
||||
options __HAVE_MM_MD_DIRECT_MAPPED_PHYS
|
||||
|
||||
options LOADADDRESS="0x80008000"
|
||||
makeoptions BOARDTYPE="TI"
|
||||
makeoptions BOARDMKFRAG="${THISARM}/conf/mk.ti"
|
||||
makeoptions CPUFLAGS="-march=armv7-a -mfpu=neon"
|
||||
makeoptions KERNEL_BASE_PHYS="0x80008000"
|
||||
makeoptions KERNEL_BASE_VIRT="0x80008000"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpufreq_dt.c,v 1.8.2.1 2019/10/08 16:56:37 martin Exp $ */
|
||||
/* $NetBSD: cpufreq_dt.c,v 1.8.2.2 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cpufreq_dt.c,v 1.8.2.1 2019/10/08 16:56:37 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cpufreq_dt.c,v 1.8.2.2 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -356,14 +356,57 @@ cpufreq_dt_parse_opp(struct cpufreq_dt_softc *sc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct fdt_opp_info *
|
||||
cpufreq_dt_lookup_opp_info(const int opp_table)
|
||||
{
|
||||
__link_set_decl(fdt_opps, struct fdt_opp_info);
|
||||
struct fdt_opp_info * const *opp;
|
||||
const struct fdt_opp_info *best_opp = NULL;
|
||||
int match, best_match = 0;
|
||||
|
||||
__link_set_foreach(opp, fdt_opps) {
|
||||
const char * const compat[] = { (*opp)->opp_compat, NULL };
|
||||
match = of_match_compatible(opp_table, compat);
|
||||
if (match > best_match) {
|
||||
best_match = match;
|
||||
best_opp = *opp;
|
||||
}
|
||||
}
|
||||
|
||||
return best_opp;
|
||||
}
|
||||
|
||||
static bool
|
||||
cpufreq_dt_opp_v2_supported(const int opp_table, const int opp_node)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
FDT_OPP(opp_v2, "operating-points-v2", cpufreq_dt_opp_v2_supported);
|
||||
|
||||
static bool
|
||||
cpufreq_dt_node_supported(const struct fdt_opp_info *opp_info, const int opp_table, const int opp_node)
|
||||
{
|
||||
if (!fdtbus_status_okay(opp_node))
|
||||
return false;
|
||||
if (of_hasprop(opp_node, "opp-suspend"))
|
||||
return false;
|
||||
|
||||
if (opp_info != NULL)
|
||||
return opp_info->opp_supported(opp_table, opp_node);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
cpufreq_dt_parse_opp_v2(struct cpufreq_dt_softc *sc)
|
||||
{
|
||||
const int phandle = sc->sc_phandle;
|
||||
struct cpufreq_dt_table *table;
|
||||
const struct fdt_opp_info *opp_info;
|
||||
const u_int *opp_uv;
|
||||
uint64_t opp_hz;
|
||||
int opp_node, len, i;
|
||||
int opp_node, len, i, index;
|
||||
|
||||
const int opp_table = fdtbus_get_phandle(phandle, "operating-points-v2");
|
||||
if (opp_table < 0)
|
||||
|
@ -378,17 +421,21 @@ cpufreq_dt_parse_opp_v2(struct cpufreq_dt_softc *sc)
|
|||
TAILQ_INSERT_TAIL(&cpufreq_dt_tables, &sc->sc_table, next);
|
||||
}
|
||||
|
||||
opp_info = cpufreq_dt_lookup_opp_info(opp_table);
|
||||
|
||||
for (opp_node = OF_child(opp_table); opp_node; opp_node = OF_peer(opp_node)) {
|
||||
if (fdtbus_status_okay(opp_node))
|
||||
sc->sc_nopp++;
|
||||
if (!cpufreq_dt_node_supported(opp_info, opp_table, opp_node))
|
||||
continue;
|
||||
sc->sc_nopp++;
|
||||
}
|
||||
|
||||
if (sc->sc_nopp == 0)
|
||||
return EINVAL;
|
||||
|
||||
sc->sc_opp = kmem_zalloc(sizeof(*sc->sc_opp) * sc->sc_nopp, KM_SLEEP);
|
||||
index = sc->sc_nopp - 1;
|
||||
for (opp_node = OF_child(opp_table), i = 0; opp_node; opp_node = OF_peer(opp_node), i++) {
|
||||
if (!fdtbus_status_okay(opp_node))
|
||||
if (!cpufreq_dt_node_supported(opp_info, opp_table, opp_node))
|
||||
continue;
|
||||
if (of_getprop_uint64(opp_node, "opp-hz", &opp_hz) != 0)
|
||||
return EINVAL;
|
||||
|
@ -396,10 +443,10 @@ cpufreq_dt_parse_opp_v2(struct cpufreq_dt_softc *sc)
|
|||
if (opp_uv == NULL || len < 1)
|
||||
return EINVAL;
|
||||
/* Table is in reverse order */
|
||||
const int index = sc->sc_nopp - i - 1;
|
||||
sc->sc_opp[index].freq_khz = (u_int)(opp_hz / 1000);
|
||||
sc->sc_opp[index].voltage_uv = be32toh(opp_uv[0]);
|
||||
of_getprop_uint32(opp_node, "clock-latency-ns", &sc->sc_opp[index].latency_ns);
|
||||
--index;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fdt_clock.c,v 1.8.4.1 2019/11/16 16:48:25 martin Exp $ */
|
||||
/* $NetBSD: fdt_clock.c,v 1.8.4.2 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fdt_clock.c,v 1.8.4.1 2019/11/16 16:48:25 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fdt_clock.c,v 1.8.4.2 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -133,8 +133,8 @@ fdtbus_clock_get_prop(int phandle, const char *clkname, const char *prop)
|
|||
return fdtbus_clock_get_index(phandle, index);
|
||||
}
|
||||
|
||||
static u_int
|
||||
fdtbus_clock_count_prop(int phandle, const char *prop)
|
||||
u_int
|
||||
fdtbus_clock_count(int phandle, const char *prop)
|
||||
{
|
||||
u_int n, clock_cells;
|
||||
int len, resid;
|
||||
|
@ -231,8 +231,8 @@ fdtbus_clock_assign(int phandle)
|
|||
if (rates == NULL)
|
||||
rates_len = 0;
|
||||
|
||||
const u_int nclocks = fdtbus_clock_count_prop(phandle, "assigned-clocks");
|
||||
const u_int nparents = fdtbus_clock_count_prop(phandle, "assigned-clock-parents");
|
||||
const u_int nclocks = fdtbus_clock_count(phandle, "assigned-clocks");
|
||||
const u_int nparents = fdtbus_clock_count(phandle, "assigned-clock-parents");
|
||||
const u_int nrates = rates_len / sizeof(*rates);
|
||||
|
||||
for (index = 0; index < nclocks; index++) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fdt_phy.c,v 1.5 2019/02/27 16:56:00 jakllsch Exp $ */
|
||||
/* $NetBSD: fdt_phy.c,v 1.5.4.1 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fdt_phy.c,v 1.5 2019/02/27 16:56:00 jakllsch Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fdt_phy.c,v 1.5.4.1 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -100,6 +100,10 @@ fdtbus_phy_get_index(int phandle, u_int index)
|
|||
|
||||
p = phys;
|
||||
for (n = 0, resid = len; resid > 0; n++) {
|
||||
if (p[0] == 0) {
|
||||
phy_cells = 0;
|
||||
goto next;
|
||||
}
|
||||
const int pc_phandle =
|
||||
fdtbus_get_phandle_from_native(be32toh(p[0]));
|
||||
if (of_getprop_uint32(pc_phandle, "#phy-cells", &phy_cells))
|
||||
|
@ -117,6 +121,7 @@ fdtbus_phy_get_index(int phandle, u_int index)
|
|||
}
|
||||
break;
|
||||
}
|
||||
next:
|
||||
resid -= (phy_cells + 1) * 4;
|
||||
p += phy_cells + 1;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fdtvar.h,v 1.52.2.2 2019/11/16 16:48:25 martin Exp $ */
|
||||
/* $NetBSD: fdtvar.h,v 1.52.2.3 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
|
||||
|
@ -247,6 +247,21 @@ static const struct fdt_console_info __CONCAT(_name,_consinfo) = { \
|
|||
}; \
|
||||
_FDT_CONSOLE_REGISTER(_name)
|
||||
|
||||
struct fdt_opp_info {
|
||||
const char * opp_compat;
|
||||
bool (*opp_supported)(const int, const int);
|
||||
};
|
||||
|
||||
#define _FDT_OPP_REGISTER(name) \
|
||||
__link_set_add_rodata(fdt_opps, __CONCAT(name,_oppinfo));
|
||||
|
||||
#define FDT_OPP(_name, _compat, _suppfn) \
|
||||
static const struct fdt_opp_info __CONCAT(_name,_oppinfo) = { \
|
||||
.opp_compat = (_compat), \
|
||||
.opp_supported = (_suppfn) \
|
||||
}; \
|
||||
_FDT_OPP_REGISTER(_name)
|
||||
|
||||
TAILQ_HEAD(fdt_conslist, fdt_console_info);
|
||||
|
||||
int fdtbus_register_interrupt_controller(device_t, int,
|
||||
|
@ -345,6 +360,7 @@ struct clk * fdtbus_clock_get(int, const char *);
|
|||
struct clk * fdtbus_clock_get_index(int, u_int);
|
||||
struct clk * fdtbus_clock_byname(const char *);
|
||||
void fdtbus_clock_assign(int);
|
||||
u_int fdtbus_clock_count(int, const char *);
|
||||
int fdtbus_clock_enable(int, const char *, bool);
|
||||
int fdtbus_clock_enable_index(int, u_int, bool);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.fdt,v 1.44.4.1 2019/11/18 19:33:10 martin Exp $
|
||||
# $NetBSD: files.fdt,v 1.44.4.2 2019/11/27 13:46:45 martin Exp $
|
||||
|
||||
include "external/bsd/libfdt/conf/files.libfdt"
|
||||
|
||||
|
@ -81,6 +81,10 @@ device syscon { } : fdt
|
|||
attach syscon at fdt
|
||||
file dev/fdt/syscon.c syscon
|
||||
|
||||
device pinctrl
|
||||
attach pinctrl at fdt with pinctrl_single
|
||||
file dev/fdt/pinctrl_single.c pinctrl_single
|
||||
|
||||
device pwmbacklight
|
||||
attach pwmbacklight at fdt
|
||||
file dev/fdt/pwm_backlight.c pwmbacklight
|
||||
|
@ -152,3 +156,8 @@ file dev/fdt/amdccp_fdt.c amdccp_fdt
|
|||
# Arasan SDHCI controller
|
||||
attach sdhc at fdt with arasan_sdhc_fdt
|
||||
file dev/fdt/arasan_sdhc_fdt.c arasan_sdhc_fdt
|
||||
|
||||
# Generic USB PHY
|
||||
device usbnopphy
|
||||
attach usbnopphy at fdt
|
||||
file dev/fdt/usbnopphy.c usbnopphy
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
/* $NetBSD: pinctrl_single.c,v 1.1.2.2 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: pinctrl_single.c,v 1.1.2.2 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/gpio.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#define PINCTRL_FLAG_PINCONF __BIT(0) /* supports generic pinconf */
|
||||
|
||||
struct pinctrl_single_config {
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
static const struct pinctrl_single_config pinctrl_config = {
|
||||
};
|
||||
|
||||
static const struct pinctrl_single_config pinconf_config = {
|
||||
.flags = PINCTRL_FLAG_PINCONF
|
||||
};
|
||||
|
||||
static const struct of_compat_data compat_data[] = {
|
||||
{ "pinctrl-single", (uintptr_t)&pinctrl_config },
|
||||
{ "pinconf-single", (uintptr_t)&pinconf_config },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
struct pinctrl_single_softc {
|
||||
device_t sc_dev;
|
||||
int sc_phandle;
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
uint32_t sc_flags;
|
||||
u_int sc_regwidth;
|
||||
u_int sc_funcmask;
|
||||
};
|
||||
|
||||
static void
|
||||
pinctrl_single_pins_write(struct pinctrl_single_softc *sc, u_int off, u_int val)
|
||||
{
|
||||
union {
|
||||
uint32_t reg32;
|
||||
uint16_t reg16;
|
||||
uint8_t reg8;
|
||||
} u;
|
||||
|
||||
aprint_debug_dev(sc->sc_dev, "writing %#x with %#x\n", off, val);
|
||||
|
||||
switch (sc->sc_regwidth) {
|
||||
case 8:
|
||||
u.reg8 = bus_space_read_1(sc->sc_bst, sc->sc_bsh, off);
|
||||
u.reg8 &= ~sc->sc_funcmask;
|
||||
u.reg8 |= val;
|
||||
bus_space_write_1(sc->sc_bst, sc->sc_bsh, off, u.reg8);
|
||||
break;
|
||||
case 16:
|
||||
u.reg16 = bus_space_read_2(sc->sc_bst, sc->sc_bsh, off);
|
||||
u.reg16 &= ~sc->sc_funcmask;
|
||||
u.reg16 |= val;
|
||||
bus_space_write_2(sc->sc_bst, sc->sc_bsh, off, u.reg16);
|
||||
break;
|
||||
case 32:
|
||||
u.reg32 = bus_space_read_4(sc->sc_bst, sc->sc_bsh, off);
|
||||
u.reg32 &= ~sc->sc_funcmask;
|
||||
u.reg32 |= val;
|
||||
bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, u.reg32);
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->sc_dev, "%s: unsupported reg width %d\n",
|
||||
__func__, sc->sc_regwidth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pinctrl_single_pins_set_config(device_t dev, const void *data, size_t len)
|
||||
{
|
||||
struct pinctrl_single_softc * const sc = device_private(dev);
|
||||
const u_int *pins;
|
||||
int pinslen;
|
||||
|
||||
if (len != 4)
|
||||
return -1;
|
||||
|
||||
const int phandle = fdtbus_get_phandle_from_native(be32dec(data));
|
||||
|
||||
pins = fdtbus_get_prop(phandle, "pinctrl-single,pins", &pinslen);
|
||||
if (pins == NULL)
|
||||
return -1;
|
||||
|
||||
while (pinslen >= 8) {
|
||||
const int off = be32toh(pins[0]);
|
||||
const int val = be32toh(pins[1]);
|
||||
|
||||
pinctrl_single_pins_write(sc, off, val);
|
||||
pins += 2;
|
||||
pinslen -= 8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fdtbus_pinctrl_controller_func pinctrl_single_pins_funcs = {
|
||||
.set_config = pinctrl_single_pins_set_config,
|
||||
};
|
||||
|
||||
static int
|
||||
pinctrl_single_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
|
||||
pinctrl_single_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct pinctrl_single_softc * const sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
const struct pinctrl_single_config *conf;
|
||||
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;
|
||||
}
|
||||
|
||||
conf = (const void *)of_search_compatible(phandle, compat_data)->data;
|
||||
|
||||
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;
|
||||
}
|
||||
sc->sc_flags = conf->flags;
|
||||
|
||||
if (of_getprop_uint32(phandle, "pinctrl-single,register-width", &sc->sc_regwidth) != 0) {
|
||||
aprint_error(": missing 'pinctrl-single,register-width' property\n");
|
||||
return;
|
||||
}
|
||||
if (of_getprop_uint32(phandle, "pinctrl-single,function-mask", &sc->sc_funcmask) != 0) {
|
||||
aprint_error(": missing 'pinctrl-single,function-mask' property\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sc->sc_regwidth) {
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
aprint_error(": register width %d not supported\n", sc->sc_regwidth);
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal("\n");
|
||||
|
||||
for (child = OF_child(phandle); child; child = OF_peer(child)) {
|
||||
if (of_hasprop(child, "pinctrl-single,pins"))
|
||||
fdtbus_register_pinctrl_config(self, child, &pinctrl_single_pins_funcs);
|
||||
}
|
||||
|
||||
fdtbus_pinctrl_set_config(phandle, "default");
|
||||
}
|
||||
|
||||
CFATTACH_DECL_NEW(pinctrl_single, sizeof(struct pinctrl_single_softc),
|
||||
pinctrl_single_match, pinctrl_single_attach, NULL, NULL);
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: syscon.c,v 1.3 2019/02/25 19:28:36 jmcneill Exp $ */
|
||||
/* $NetBSD: syscon.c,v 1.3.6.1 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: syscon.c,v 1.3 2019/02/25 19:28:36 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: syscon.c,v 1.3.6.1 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
|
@ -113,6 +113,7 @@ syscon_attach(device_t parent, device_t self, void *aux)
|
|||
const int phandle = faa->faa_phandle;
|
||||
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");
|
||||
|
@ -138,4 +139,8 @@ syscon_attach(device_t parent, device_t self, void *aux)
|
|||
fdtbus_register_syscon(self, phandle, &sc->sc_syscon);
|
||||
|
||||
fdt_add_bus(self, phandle, faa);
|
||||
|
||||
child = of_find_firstchild_byname(phandle, "clocks");
|
||||
if (child > 0)
|
||||
fdt_add_bus(self, child, faa);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/* $NetBSD: usbnopphy.c,v 1.1.2.2 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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: usbnopphy.c,v 1.1.2.2 2019/11/27 13:46:45 martin 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>
|
||||
|
||||
static int usbnopphy_match(device_t, cfdata_t, void *);
|
||||
static void usbnopphy_attach(device_t, device_t, void *);
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"usb-nop-xceiv",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct usbnopphy_softc {
|
||||
device_t sc_dev;
|
||||
|
||||
struct clk *sc_clk;
|
||||
struct fdtbus_regulator *sc_reg;
|
||||
struct fdtbus_gpio_pin *sc_pin_reset;
|
||||
struct fdtbus_gpio_pin *sc_pin_vbus_det;
|
||||
};
|
||||
|
||||
CFATTACH_DECL_NEW(usbnopphy, sizeof(struct usbnopphy_softc),
|
||||
usbnopphy_match, usbnopphy_attach, NULL, NULL);
|
||||
|
||||
static void *
|
||||
usbnopphy_acquire(device_t dev, const void *data, size_t len)
|
||||
{
|
||||
struct usbnopphy_softc * const sc = device_private(dev);
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
static void
|
||||
usbnopphy_release(device_t dev, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
usbnopphy_enable(device_t dev, void *priv, bool enable)
|
||||
{
|
||||
struct usbnopphy_softc * const sc = device_private(dev);
|
||||
int error;
|
||||
|
||||
if (enable) {
|
||||
if (sc->sc_reg != NULL) {
|
||||
error = fdtbus_regulator_enable(sc->sc_reg);
|
||||
if (error != 0)
|
||||
return error;
|
||||
}
|
||||
if (sc->sc_clk != NULL) {
|
||||
error = clk_enable(sc->sc_clk);
|
||||
if (error != 0)
|
||||
return error;
|
||||
}
|
||||
if (sc->sc_pin_reset != NULL) {
|
||||
fdtbus_gpio_write(sc->sc_pin_reset, 1);
|
||||
delay(20000);
|
||||
fdtbus_gpio_write(sc->sc_pin_reset, 0);
|
||||
}
|
||||
} else {
|
||||
if (sc->sc_pin_reset != NULL)
|
||||
fdtbus_gpio_write(sc->sc_pin_reset, 1);
|
||||
if (sc->sc_reg != NULL)
|
||||
fdtbus_regulator_disable(sc->sc_reg);
|
||||
if (sc->sc_clk != NULL)
|
||||
clk_disable(sc->sc_clk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct fdtbus_phy_controller_func usbnopphy_funcs = {
|
||||
.acquire = usbnopphy_acquire,
|
||||
.release = usbnopphy_release,
|
||||
.enable = usbnopphy_enable,
|
||||
};
|
||||
|
||||
static int
|
||||
usbnopphy_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
|
||||
usbnopphy_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct usbnopphy_softc * const sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
|
||||
sc->sc_dev = self;
|
||||
|
||||
sc->sc_reg = fdtbus_regulator_acquire(phandle, "vbus-regulator");
|
||||
sc->sc_clk = fdtbus_clock_get(phandle, "main_clk");
|
||||
sc->sc_pin_reset = fdtbus_gpio_acquire(phandle, "reset-gpios", GPIO_PIN_OUTPUT);
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": USB PHY\n");
|
||||
|
||||
fdtbus_register_phy_controller(self, phandle, &usbnopphy_funcs);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: at24cxx.c,v 1.31 2019/03/26 09:22:17 mlelstv Exp $ */
|
||||
/* $NetBSD: at24cxx.c,v 1.31.4.1 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wasabi Systems, Inc.
|
||||
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: at24cxx.c,v 1.31 2019/03/26 09:22:17 mlelstv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: at24cxx.c,v 1.31.4.1 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -125,6 +125,7 @@ static const struct device_compatible_entry compat_data[] = {
|
|||
{ "i2c-at34c02", 256 },
|
||||
{ "atmel,24c02", 256 },
|
||||
{ "atmel,24c16", 2048 },
|
||||
{ "atmel,24c256", 32768 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.i2c,v 1.100 2019/07/24 05:25:32 thorpej Exp $
|
||||
# $NetBSD: files.i2c,v 1.100.2.1 2019/11/27 13:46:45 martin Exp $
|
||||
|
||||
obsolete defflag opt_i2cbus.h I2C_SCAN
|
||||
define i2cbus { }
|
||||
|
@ -196,14 +196,11 @@ device ibmhawk: sysmon_envsys
|
|||
attach ibmhawk at iic
|
||||
file dev/i2c/ibmhawk.c ibmhawk
|
||||
|
||||
# TI TPS65950 OMAP Power Management and System Companion Device
|
||||
device tps65950pm: sysmon_wdog
|
||||
attach tps65950pm at iic
|
||||
file dev/i2c/tps65950.c tps65950pm
|
||||
|
||||
# TI TPS65217
|
||||
device tps65217pmic: sysmon_envsys
|
||||
device tps65217pmic { }: sysmon_envsys
|
||||
device tps65217reg: tps65217pmic
|
||||
attach tps65217pmic at iic
|
||||
attach tps65217reg at tps65217pmic
|
||||
file dev/i2c/tps65217pmic.c tps65217pmic needs-flag
|
||||
|
||||
# Microchip MCP980x
|
||||
|
@ -371,3 +368,13 @@ file dev/i2c/anxedp.c anxedp
|
|||
device pcapwm: pwm
|
||||
attach pcapwm at iic
|
||||
file dev/i2c/pca9685.c pcapwm
|
||||
|
||||
# TI TWL4030 Power Management IC
|
||||
device twl
|
||||
attach twl at iic
|
||||
file dev/i2c/twl4030.c twl
|
||||
|
||||
# NXP TDA19988 HDMI encoder
|
||||
device tdahdmi: edid, videomode, drmkms, drmkms_i2c
|
||||
attach tdahdmi at iic
|
||||
file dev/i2c/tda19988.c tdahdmi
|
||||
|
|
|
@ -0,0 +1,940 @@
|
|||
/* $NetBSD: tda19988.c,v 1.3.2.2 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@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: tda19988.c,v 1.3.2.2 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
/*
|
||||
* NXP TDA19988 HDMI encoder
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <dev/i2c/i2cvar.h>
|
||||
#include <dev/i2c/ddcvar.h>
|
||||
#include <dev/i2c/ddcreg.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
#include <dev/fdt/fdt_port.h>
|
||||
|
||||
#include <dev/videomode/videomode.h>
|
||||
#include <dev/videomode/edidvar.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
|
||||
enum {
|
||||
TDA19988_PORT_INPUT = 0
|
||||
};
|
||||
|
||||
#define MKREG(page, addr) (((page) << 8) | (addr))
|
||||
|
||||
#define REGPAGE(reg) (((reg) >> 8) & 0xff)
|
||||
#define REGADDR(reg) ((reg) & 0xff)
|
||||
|
||||
#define TDA_VERSION MKREG(0x00, 0x00)
|
||||
#define TDA_MAIN_CNTRL0 MKREG(0x00, 0x01)
|
||||
#define MAIN_CNTRL0_SR (1 << 0)
|
||||
#define TDA_VERSION_MSB MKREG(0x00, 0x02)
|
||||
#define TDA_SOFTRESET MKREG(0x00, 0x0a)
|
||||
#define SOFTRESET_I2C (1 << 1)
|
||||
#define SOFTRESET_AUDIO (1 << 0)
|
||||
#define TDA_DDC_CTRL MKREG(0x00, 0x0b)
|
||||
#define DDC_ENABLE 0
|
||||
#define TDA_CCLK MKREG(0x00, 0x0c)
|
||||
#define CCLK_ENABLE 1
|
||||
#define TDA_INT_FLAGS_2 MKREG(0x00, 0x11)
|
||||
#define INT_FLAGS_2_EDID_BLK_RD (1 << 1)
|
||||
|
||||
#define TDA_VIP_CNTRL_0 MKREG(0x00, 0x20)
|
||||
#define TDA_VIP_CNTRL_1 MKREG(0x00, 0x21)
|
||||
#define TDA_VIP_CNTRL_2 MKREG(0x00, 0x22)
|
||||
#define TDA_VIP_CNTRL_3 MKREG(0x00, 0x23)
|
||||
#define VIP_CNTRL_3_SYNC_HS (2 << 4)
|
||||
#define VIP_CNTRL_3_V_TGL (1 << 2)
|
||||
#define VIP_CNTRL_3_H_TGL (1 << 1)
|
||||
|
||||
#define TDA_VIP_CNTRL_4 MKREG(0x00, 0x24)
|
||||
#define VIP_CNTRL_4_BLANKIT_NDE (0 << 2)
|
||||
#define VIP_CNTRL_4_BLANKIT_HS_VS (1 << 2)
|
||||
#define VIP_CNTRL_4_BLANKIT_NHS_VS (2 << 2)
|
||||
#define VIP_CNTRL_4_BLANKIT_HE_VE (3 << 2)
|
||||
#define VIP_CNTRL_4_BLC_NONE (0 << 0)
|
||||
#define VIP_CNTRL_4_BLC_RGB444 (1 << 0)
|
||||
#define VIP_CNTRL_4_BLC_YUV444 (2 << 0)
|
||||
#define VIP_CNTRL_4_BLC_YUV422 (3 << 0)
|
||||
#define TDA_VIP_CNTRL_5 MKREG(0x00, 0x25)
|
||||
#define VIP_CNTRL_5_SP_CNT(n) (((n) & 3) << 1)
|
||||
#define TDA_MUX_VP_VIP_OUT MKREG(0x00, 0x27)
|
||||
#define TDA_MAT_CONTRL MKREG(0x00, 0x80)
|
||||
#define MAT_CONTRL_MAT_BP (1 << 2)
|
||||
#define TDA_VIDFORMAT MKREG(0x00, 0xa0)
|
||||
#define TDA_REFPIX_MSB MKREG(0x00, 0xa1)
|
||||
#define TDA_REFPIX_LSB MKREG(0x00, 0xa2)
|
||||
#define TDA_REFLINE_MSB MKREG(0x00, 0xa3)
|
||||
#define TDA_REFLINE_LSB MKREG(0x00, 0xa4)
|
||||
#define TDA_NPIX_MSB MKREG(0x00, 0xa5)
|
||||
#define TDA_NPIX_LSB MKREG(0x00, 0xa6)
|
||||
#define TDA_NLINE_MSB MKREG(0x00, 0xa7)
|
||||
#define TDA_NLINE_LSB MKREG(0x00, 0xa8)
|
||||
#define TDA_VS_LINE_STRT_1_MSB MKREG(0x00, 0xa9)
|
||||
#define TDA_VS_LINE_STRT_1_LSB MKREG(0x00, 0xaa)
|
||||
#define TDA_VS_PIX_STRT_1_MSB MKREG(0x00, 0xab)
|
||||
#define TDA_VS_PIX_STRT_1_LSB MKREG(0x00, 0xac)
|
||||
#define TDA_VS_LINE_END_1_MSB MKREG(0x00, 0xad)
|
||||
#define TDA_VS_LINE_END_1_LSB MKREG(0x00, 0xae)
|
||||
#define TDA_VS_PIX_END_1_MSB MKREG(0x00, 0xaf)
|
||||
#define TDA_VS_PIX_END_1_LSB MKREG(0x00, 0xb0)
|
||||
#define TDA_VS_LINE_STRT_2_MSB MKREG(0x00, 0xb1)
|
||||
#define TDA_VS_LINE_STRT_2_LSB MKREG(0x00, 0xb2)
|
||||
#define TDA_VS_PIX_STRT_2_MSB MKREG(0x00, 0xb3)
|
||||
#define TDA_VS_PIX_STRT_2_LSB MKREG(0x00, 0xb4)
|
||||
#define TDA_VS_LINE_END_2_MSB MKREG(0x00, 0xb5)
|
||||
#define TDA_VS_LINE_END_2_LSB MKREG(0x00, 0xb6)
|
||||
#define TDA_VS_PIX_END_2_MSB MKREG(0x00, 0xb7)
|
||||
#define TDA_VS_PIX_END_2_LSB MKREG(0x00, 0xb8)
|
||||
#define TDA_HS_PIX_START_MSB MKREG(0x00, 0xb9)
|
||||
#define TDA_HS_PIX_START_LSB MKREG(0x00, 0xba)
|
||||
#define TDA_HS_PIX_STOP_MSB MKREG(0x00, 0xbb)
|
||||
#define TDA_HS_PIX_STOP_LSB MKREG(0x00, 0xbc)
|
||||
#define TDA_VWIN_START_1_MSB MKREG(0x00, 0xbd)
|
||||
#define TDA_VWIN_START_1_LSB MKREG(0x00, 0xbe)
|
||||
#define TDA_VWIN_END_1_MSB MKREG(0x00, 0xbf)
|
||||
#define TDA_VWIN_END_1_LSB MKREG(0x00, 0xc0)
|
||||
#define TDA_VWIN_START_2_MSB MKREG(0x00, 0xc1)
|
||||
#define TDA_VWIN_START_2_LSB MKREG(0x00, 0xc2)
|
||||
#define TDA_VWIN_END_2_MSB MKREG(0x00, 0xc3)
|
||||
#define TDA_VWIN_END_2_LSB MKREG(0x00, 0xc4)
|
||||
#define TDA_DE_START_MSB MKREG(0x00, 0xc5)
|
||||
#define TDA_DE_START_LSB MKREG(0x00, 0xc6)
|
||||
#define TDA_DE_STOP_MSB MKREG(0x00, 0xc7)
|
||||
#define TDA_DE_STOP_LSB MKREG(0x00, 0xc8)
|
||||
|
||||
#define TDA_TBG_CNTRL_0 MKREG(0x00, 0xca)
|
||||
#define TBG_CNTRL_0_SYNC_ONCE (1 << 7)
|
||||
#define TBG_CNTRL_0_SYNC_MTHD (1 << 6)
|
||||
|
||||
#define TDA_TBG_CNTRL_1 MKREG(0x00, 0xcb)
|
||||
#define TBG_CNTRL_1_DWIN_DIS (1 << 6)
|
||||
#define TBG_CNTRL_1_TGL_EN (1 << 2)
|
||||
#define TBG_CNTRL_1_V_TGL (1 << 1)
|
||||
#define TBG_CNTRL_1_H_TGL (1 << 0)
|
||||
|
||||
#define TDA_HVF_CNTRL_0 MKREG(0x00, 0xe4)
|
||||
#define HVF_CNTRL_0_PREFIL_NONE (0 << 2)
|
||||
#define HVF_CNTRL_0_INTPOL_BYPASS (0 << 0)
|
||||
#define TDA_HVF_CNTRL_1 MKREG(0x00, 0xe5)
|
||||
#define HVF_CNTRL_1_VQR(x) (((x) & 3) << 2)
|
||||
#define HVF_CNTRL_1_VQR_FULL HVF_CNTRL_1_VQR(0)
|
||||
#define TDA_ENABLE_SPACE MKREG(0x00, 0xd6)
|
||||
#define TDA_RPT_CNTRL MKREG(0x00, 0xf0)
|
||||
|
||||
#define TDA_PLL_SERIAL_1 MKREG(0x02, 0x00)
|
||||
#define PLL_SERIAL_1_SRL_MAN_IP (1 << 6)
|
||||
#define TDA_PLL_SERIAL_2 MKREG(0x02, 0x01)
|
||||
#define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4)
|
||||
#define PLL_SERIAL_2_SRL_NOSC(x) (((x) & 0x3) << 0)
|
||||
#define TDA_PLL_SERIAL_3 MKREG(0x02, 0x02)
|
||||
#define PLL_SERIAL_3_SRL_PXIN_SEL (1 << 4)
|
||||
#define PLL_SERIAL_3_SRL_DE (1 << 2)
|
||||
#define PLL_SERIAL_3_SRL_CCIR (1 << 0)
|
||||
#define TDA_SERIALIZER MKREG(0x02, 0x03)
|
||||
#define TDA_BUFFER_OUT MKREG(0x02, 0x04)
|
||||
#define TDA_PLL_SCG1 MKREG(0x02, 0x05)
|
||||
#define TDA_PLL_SCG2 MKREG(0x02, 0x06)
|
||||
#define TDA_PLL_SCGN1 MKREG(0x02, 0x07)
|
||||
#define TDA_PLL_SCGN2 MKREG(0x02, 0x08)
|
||||
#define TDA_PLL_SCGR1 MKREG(0x02, 0x09)
|
||||
#define TDA_PLL_SCGR2 MKREG(0x02, 0x0a)
|
||||
|
||||
#define TDA_SEL_CLK MKREG(0x02, 0x11)
|
||||
#define SEL_CLK_ENA_SC_CLK (1 << 3)
|
||||
#define SEL_CLK_SEL_VRF_CLK(x) (((x) & 3) << 1)
|
||||
#define SEL_CLK_SEL_CLK1 (1 << 0)
|
||||
#define TDA_ANA_GENERAL MKREG(0x02, 0x12)
|
||||
|
||||
#define TDA_EDID_DATA0 MKREG(0x09, 0x00)
|
||||
#define TDA_EDID_CTRL MKREG(0x09, 0xfa)
|
||||
#define TDA_DDC_ADDR MKREG(0x09, 0xfb)
|
||||
#define TDA_DDC_OFFS MKREG(0x09, 0xfc)
|
||||
#define TDA_DDC_SEGM_ADDR MKREG(0x09, 0xfd)
|
||||
#define TDA_DDC_SEGM MKREG(0x09, 0xfe)
|
||||
|
||||
#define TDA_IF_VSP MKREG(0x10, 0x20)
|
||||
#define TDA_IF_AVI MKREG(0x10, 0x40)
|
||||
#define TDA_IF_SPD MKREG(0x10, 0x60)
|
||||
#define TDA_IF_AUD MKREG(0x10, 0x80)
|
||||
#define TDA_IF_MPS MKREG(0x10, 0xa0)
|
||||
|
||||
#define TDA_ENC_CNTRL MKREG(0x11, 0x0d)
|
||||
#define ENC_CNTRL_DVI_MODE (0 << 2)
|
||||
#define ENC_CNTRL_HDMI_MODE (1 << 2)
|
||||
#define TDA_DIP_IF_FLAGS MKREG(0x11, 0x0f)
|
||||
#define DIP_IF_FLAGS_IF5 (1 << 5)
|
||||
#define DIP_IF_FLAGS_IF4 (1 << 4)
|
||||
#define DIP_IF_FLAGS_IF3 (1 << 3)
|
||||
#define DIP_IF_FLAGS_IF2 (1 << 2) /* AVI IF on page 10h */
|
||||
#define DIP_IF_FLAGS_IF1 (1 << 1)
|
||||
|
||||
#define TDA_TX3 MKREG(0x12, 0x9a)
|
||||
#define TDA_TX4 MKREG(0x12, 0x9b)
|
||||
#define TX4_PD_RAM (1 << 1)
|
||||
#define TDA_HDCP_TX33 MKREG(0x12, 0xb8)
|
||||
#define HDCP_TX33_HDMI (1 << 1)
|
||||
|
||||
#define TDA_CURPAGE_ADDR 0xff
|
||||
|
||||
#define TDA_CEC_RXSHPDLEV 0xfe
|
||||
#define RXSHPDLEV_HPD __BIT(1)
|
||||
|
||||
#define TDA_CEC_ENAMODS 0xff
|
||||
#define ENAMODS_RXSENS (1 << 2)
|
||||
#define ENAMODS_HDMI (1 << 1)
|
||||
#define TDA_CEC_FRO_IM_CLK_CTRL 0xfb
|
||||
#define CEC_FRO_IM_CLK_CTRL_GHOST_DIS (1 << 7)
|
||||
#define CEC_FRO_IM_CLK_CTRL_IMCLK_SEL (1 << 1)
|
||||
|
||||
/* EDID reading */
|
||||
#define MAX_READ_ATTEMPTS 100
|
||||
|
||||
/* EDID fields */
|
||||
#define EDID_MODES0 35
|
||||
#define EDID_MODES1 36
|
||||
#define EDID_TIMING_START 38
|
||||
#define EDID_TIMING_END 54
|
||||
#define EDID_TIMING_X(v) (((v) + 31) * 8)
|
||||
#define EDID_FREQ(v) (((v) & 0x3f) + 60)
|
||||
#define EDID_RATIO(v) (((v) >> 6) & 0x3)
|
||||
#define EDID_RATIO_10x16 0
|
||||
#define EDID_RATIO_3x4 1
|
||||
#define EDID_RATIO_4x5 2
|
||||
#define EDID_RATIO_9x16 3
|
||||
|
||||
#define TDA19988 0x0301
|
||||
|
||||
static const struct device_compatible_entry compat_data[] = {
|
||||
{ "nxp,tda998x", 1 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
struct tda19988_softc;
|
||||
|
||||
struct tda19988_connector {
|
||||
struct drm_connector base;
|
||||
struct tda19988_softc *sc;
|
||||
};
|
||||
|
||||
struct tda19988_softc {
|
||||
device_t sc_dev;
|
||||
int sc_phandle;
|
||||
i2c_tag_t sc_i2c;
|
||||
i2c_addr_t sc_addr;
|
||||
uint32_t sc_cec_addr;
|
||||
uint16_t sc_version;
|
||||
int sc_current_page;
|
||||
uint8_t *sc_edid;
|
||||
uint32_t sc_edid_len;
|
||||
bool sc_edid_valid;
|
||||
|
||||
struct drm_bridge sc_bridge;
|
||||
struct tda19988_connector sc_connector;
|
||||
|
||||
struct fdt_device_ports sc_ports;
|
||||
|
||||
enum drm_connector_status sc_last_status;
|
||||
};
|
||||
|
||||
#define to_tda_connector(x) container_of(x, struct tda19988_connector, base)
|
||||
|
||||
static int
|
||||
tda19988_set_page(struct tda19988_softc *sc, uint8_t page)
|
||||
{
|
||||
uint8_t buf[2] = { TDA_CURPAGE_ADDR, page };
|
||||
int result;
|
||||
|
||||
result = iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, buf, 2, NULL, 0,
|
||||
cold ? I2C_F_POLL : 0);
|
||||
if (result == 0)
|
||||
sc->sc_current_page = page;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
tda19988_cec_read(struct tda19988_softc *sc, uint8_t addr, uint8_t *data)
|
||||
{
|
||||
return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_cec_addr, &addr, 1, data, 1,
|
||||
cold ? I2C_F_POLL : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
tda19988_cec_write(struct tda19988_softc *sc, uint8_t addr, uint8_t data)
|
||||
{
|
||||
uint8_t buf[2] = { addr, data };
|
||||
|
||||
return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_cec_addr, buf, 2, NULL, 0,
|
||||
cold ? I2C_F_POLL : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
tda19988_block_read(struct tda19988_softc *sc, uint16_t addr, uint8_t *data, int len)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
reg = REGADDR(addr);
|
||||
|
||||
if (sc->sc_current_page != REGPAGE(addr))
|
||||
tda19988_set_page(sc, REGPAGE(addr));
|
||||
|
||||
return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, ®, 1, data, len,
|
||||
cold ? I2C_F_POLL : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
tda19988_reg_read(struct tda19988_softc *sc, uint16_t addr, uint8_t *data)
|
||||
{
|
||||
uint8_t reg;
|
||||
|
||||
reg = REGADDR(addr);
|
||||
|
||||
if (sc->sc_current_page != REGPAGE(addr))
|
||||
tda19988_set_page(sc, REGPAGE(addr));
|
||||
|
||||
return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, ®, 1, data, 1,
|
||||
cold ? I2C_F_POLL : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
tda19988_reg_write(struct tda19988_softc *sc, uint16_t addr, uint8_t data)
|
||||
{
|
||||
uint8_t buf[2] = { REGADDR(addr), data };
|
||||
|
||||
if (sc->sc_current_page != REGPAGE(addr))
|
||||
tda19988_set_page(sc, REGPAGE(addr));
|
||||
|
||||
return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, buf, 2, NULL, 0,
|
||||
cold ? I2C_F_POLL : 0);
|
||||
}
|
||||
|
||||
static int
|
||||
tda19988_reg_write2(struct tda19988_softc *sc, uint16_t address, uint16_t data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
buf[0] = REGADDR(address);
|
||||
buf[1] = (data >> 8);
|
||||
buf[2] = (data & 0xff);
|
||||
|
||||
if (sc->sc_current_page != REGPAGE(address))
|
||||
tda19988_set_page(sc, REGPAGE(address));
|
||||
|
||||
return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, buf, 3, NULL, 0,
|
||||
cold ? I2C_F_POLL : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_reg_set(struct tda19988_softc *sc, uint16_t addr, uint8_t flags)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
tda19988_reg_read(sc, addr, &data);
|
||||
data |= flags;
|
||||
tda19988_reg_write(sc, addr, data);
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_reg_clear(struct tda19988_softc *sc, uint16_t addr, uint8_t flags)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
tda19988_reg_read(sc, addr, &data);
|
||||
data &= ~flags;
|
||||
tda19988_reg_write(sc, addr, data);
|
||||
}
|
||||
|
||||
static int
|
||||
tda19988_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct i2c_attach_args * const ia = aux;
|
||||
int match_result;
|
||||
|
||||
if (iic_use_direct_match(ia, match, compat_data, &match_result))
|
||||
return match_result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_init_encoder(struct tda19988_softc *sc, const struct drm_display_mode *mode)
|
||||
{
|
||||
uint16_t ref_pix, ref_line, n_pix, n_line;
|
||||
uint16_t hs_pix_start, hs_pix_stop;
|
||||
uint16_t vs1_pix_start, vs1_pix_stop;
|
||||
uint16_t vs1_line_start, vs1_line_end;
|
||||
uint16_t vs2_pix_start, vs2_pix_stop;
|
||||
uint16_t vs2_line_start, vs2_line_end;
|
||||
uint16_t vwin1_line_start, vwin1_line_end;
|
||||
uint16_t vwin2_line_start, vwin2_line_end;
|
||||
uint16_t de_start, de_stop;
|
||||
uint8_t reg, div;
|
||||
|
||||
n_pix = mode->crtc_htotal;
|
||||
n_line = mode->crtc_vtotal;
|
||||
|
||||
hs_pix_stop = mode->crtc_hsync_end - mode->crtc_hdisplay;
|
||||
hs_pix_start = mode->crtc_hsync_start - mode->crtc_hdisplay;
|
||||
|
||||
de_stop = mode->crtc_htotal;
|
||||
de_start = mode->crtc_htotal - mode->crtc_hdisplay;
|
||||
ref_pix = hs_pix_start + 3;
|
||||
|
||||
if (mode->flags & DRM_MODE_FLAG_HSKEW)
|
||||
ref_pix += mode->crtc_hskew;
|
||||
|
||||
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) == 0) {
|
||||
ref_line = 1 + mode->crtc_vsync_start - mode->crtc_vdisplay;
|
||||
vwin1_line_start = mode->crtc_vtotal - mode->crtc_vdisplay - 1;
|
||||
vwin1_line_end = vwin1_line_start + mode->crtc_vdisplay;
|
||||
|
||||
vs1_pix_start = vs1_pix_stop = hs_pix_start;
|
||||
vs1_line_start = mode->crtc_vsync_start - mode->crtc_vdisplay;
|
||||
vs1_line_end = vs1_line_start + mode->crtc_vsync_end - mode->crtc_vsync_start;
|
||||
|
||||
vwin2_line_start = vwin2_line_end = 0;
|
||||
vs2_pix_start = vs2_pix_stop = 0;
|
||||
vs2_line_start = vs2_line_end = 0;
|
||||
} else {
|
||||
ref_line = 1 + (mode->crtc_vsync_start - mode->crtc_vdisplay)/2;
|
||||
vwin1_line_start = (mode->crtc_vtotal - mode->crtc_vdisplay)/2;
|
||||
vwin1_line_end = vwin1_line_start + mode->crtc_vdisplay/2;
|
||||
|
||||
vs1_pix_start = vs1_pix_stop = hs_pix_start;
|
||||
vs1_line_start = (mode->crtc_vsync_start - mode->crtc_vdisplay)/2;
|
||||
vs1_line_end = vs1_line_start + (mode->crtc_vsync_end - mode->crtc_vsync_start)/2;
|
||||
|
||||
vwin2_line_start = vwin1_line_start + mode->crtc_vtotal/2;
|
||||
vwin2_line_end = vwin2_line_start + mode->crtc_vdisplay/2;
|
||||
|
||||
vs2_pix_start = vs2_pix_stop = hs_pix_start + mode->crtc_htotal/2;
|
||||
vs2_line_start = vs1_line_start + mode->crtc_vtotal/2 ;
|
||||
vs2_line_end = vs2_line_start + (mode->crtc_vsync_end - mode->crtc_vsync_start)/2;
|
||||
}
|
||||
|
||||
div = 148500 / mode->crtc_clock;
|
||||
if (div != 0) {
|
||||
div--;
|
||||
if (div > 3)
|
||||
div = 3;
|
||||
}
|
||||
|
||||
/* set HDMI HDCP mode off */
|
||||
tda19988_reg_set(sc, TDA_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS);
|
||||
tda19988_reg_clear(sc, TDA_HDCP_TX33, HDCP_TX33_HDMI);
|
||||
tda19988_reg_write(sc, TDA_ENC_CNTRL, ENC_CNTRL_DVI_MODE);
|
||||
|
||||
/* no pre-filter or interpolator */
|
||||
tda19988_reg_write(sc, TDA_HVF_CNTRL_0,
|
||||
HVF_CNTRL_0_INTPOL_BYPASS | HVF_CNTRL_0_PREFIL_NONE);
|
||||
tda19988_reg_write(sc, TDA_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0));
|
||||
tda19988_reg_write(sc, TDA_VIP_CNTRL_4,
|
||||
VIP_CNTRL_4_BLANKIT_NDE | VIP_CNTRL_4_BLC_NONE);
|
||||
|
||||
tda19988_reg_clear(sc, TDA_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR);
|
||||
tda19988_reg_clear(sc, TDA_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IP);
|
||||
tda19988_reg_clear(sc, TDA_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE);
|
||||
tda19988_reg_write(sc, TDA_SERIALIZER, 0);
|
||||
tda19988_reg_write(sc, TDA_HVF_CNTRL_1, HVF_CNTRL_1_VQR_FULL);
|
||||
|
||||
tda19988_reg_write(sc, TDA_RPT_CNTRL, 0);
|
||||
tda19988_reg_write(sc, TDA_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) |
|
||||
SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK);
|
||||
|
||||
tda19988_reg_write(sc, TDA_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) |
|
||||
PLL_SERIAL_2_SRL_PR(0));
|
||||
|
||||
tda19988_reg_set(sc, TDA_MAT_CONTRL, MAT_CONTRL_MAT_BP);
|
||||
|
||||
tda19988_reg_write(sc, TDA_ANA_GENERAL, 0x09);
|
||||
|
||||
tda19988_reg_clear(sc, TDA_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD);
|
||||
|
||||
/*
|
||||
* Sync on rising HSYNC/VSYNC
|
||||
*/
|
||||
reg = VIP_CNTRL_3_SYNC_HS;
|
||||
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
|
||||
reg |= VIP_CNTRL_3_H_TGL;
|
||||
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
|
||||
reg |= VIP_CNTRL_3_V_TGL;
|
||||
tda19988_reg_write(sc, TDA_VIP_CNTRL_3, reg);
|
||||
|
||||
reg = TBG_CNTRL_1_TGL_EN;
|
||||
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
|
||||
reg |= TBG_CNTRL_1_H_TGL;
|
||||
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
|
||||
reg |= TBG_CNTRL_1_V_TGL;
|
||||
tda19988_reg_write(sc, TDA_TBG_CNTRL_1, reg);
|
||||
|
||||
/* Program timing */
|
||||
tda19988_reg_write(sc, TDA_VIDFORMAT, 0x00);
|
||||
|
||||
tda19988_reg_write2(sc, TDA_REFPIX_MSB, ref_pix);
|
||||
tda19988_reg_write2(sc, TDA_REFLINE_MSB, ref_line);
|
||||
tda19988_reg_write2(sc, TDA_NPIX_MSB, n_pix);
|
||||
tda19988_reg_write2(sc, TDA_NLINE_MSB, n_line);
|
||||
|
||||
tda19988_reg_write2(sc, TDA_VS_LINE_STRT_1_MSB, vs1_line_start);
|
||||
tda19988_reg_write2(sc, TDA_VS_PIX_STRT_1_MSB, vs1_pix_start);
|
||||
tda19988_reg_write2(sc, TDA_VS_LINE_END_1_MSB, vs1_line_end);
|
||||
tda19988_reg_write2(sc, TDA_VS_PIX_END_1_MSB, vs1_pix_stop);
|
||||
tda19988_reg_write2(sc, TDA_VS_LINE_STRT_2_MSB, vs2_line_start);
|
||||
tda19988_reg_write2(sc, TDA_VS_PIX_STRT_2_MSB, vs2_pix_start);
|
||||
tda19988_reg_write2(sc, TDA_VS_LINE_END_2_MSB, vs2_line_end);
|
||||
tda19988_reg_write2(sc, TDA_VS_PIX_END_2_MSB, vs2_pix_stop);
|
||||
tda19988_reg_write2(sc, TDA_HS_PIX_START_MSB, hs_pix_start);
|
||||
tda19988_reg_write2(sc, TDA_HS_PIX_STOP_MSB, hs_pix_stop);
|
||||
tda19988_reg_write2(sc, TDA_VWIN_START_1_MSB, vwin1_line_start);
|
||||
tda19988_reg_write2(sc, TDA_VWIN_END_1_MSB, vwin1_line_end);
|
||||
tda19988_reg_write2(sc, TDA_VWIN_START_2_MSB, vwin2_line_start);
|
||||
tda19988_reg_write2(sc, TDA_VWIN_END_2_MSB, vwin2_line_end);
|
||||
tda19988_reg_write2(sc, TDA_DE_START_MSB, de_start);
|
||||
tda19988_reg_write2(sc, TDA_DE_STOP_MSB, de_stop);
|
||||
|
||||
if (sc->sc_version == TDA19988)
|
||||
tda19988_reg_write(sc, TDA_ENABLE_SPACE, 0x00);
|
||||
|
||||
/* must be last register set */
|
||||
tda19988_reg_clear(sc, TDA_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE);
|
||||
}
|
||||
|
||||
static int
|
||||
tda19988_read_edid_block(struct tda19988_softc *sc, uint8_t *buf, int block)
|
||||
{
|
||||
int attempt, err;
|
||||
uint8_t data;
|
||||
|
||||
err = 0;
|
||||
|
||||
tda19988_reg_set(sc, TDA_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
|
||||
|
||||
/* Block 0 */
|
||||
tda19988_reg_write(sc, TDA_DDC_ADDR, 0xa0);
|
||||
tda19988_reg_write(sc, TDA_DDC_OFFS, (block % 2) ? 128 : 0);
|
||||
tda19988_reg_write(sc, TDA_DDC_SEGM_ADDR, 0x60);
|
||||
tda19988_reg_write(sc, TDA_DDC_SEGM, block / 2);
|
||||
|
||||
tda19988_reg_write(sc, TDA_EDID_CTRL, 1);
|
||||
tda19988_reg_write(sc, TDA_EDID_CTRL, 0);
|
||||
|
||||
data = 0;
|
||||
for (attempt = 0; attempt < MAX_READ_ATTEMPTS; attempt++) {
|
||||
tda19988_reg_read(sc, TDA_INT_FLAGS_2, &data);
|
||||
if (data & INT_FLAGS_2_EDID_BLK_RD)
|
||||
break;
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
if (attempt == MAX_READ_ATTEMPTS) {
|
||||
err = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (tda19988_block_read(sc, TDA_EDID_DATA0, buf, EDID_LENGTH) != 0) {
|
||||
err = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
tda19988_reg_clear(sc, TDA_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
tda19988_read_edid(struct tda19988_softc *sc)
|
||||
{
|
||||
int err;
|
||||
int blocks, i;
|
||||
uint8_t *buf, *edid;
|
||||
|
||||
err = 0;
|
||||
if (sc->sc_version == TDA19988)
|
||||
tda19988_reg_clear(sc, TDA_TX4, TX4_PD_RAM);
|
||||
|
||||
err = tda19988_read_edid_block(sc, sc->sc_edid, 0);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
blocks = sc->sc_edid[0x7e];
|
||||
if (blocks > 0) {
|
||||
if (sc->sc_edid_len != EDID_LENGTH*(blocks+1)) {
|
||||
edid = kmem_zalloc(EDID_LENGTH*(blocks+1), KM_SLEEP);
|
||||
memcpy(edid, sc->sc_edid, EDID_LENGTH);
|
||||
kmem_free(sc->sc_edid, sc->sc_edid_len);
|
||||
sc->sc_edid = edid;
|
||||
sc->sc_edid_len = EDID_LENGTH*(blocks+1);
|
||||
}
|
||||
for (i = 0; i < blocks; i++) {
|
||||
/* TODO: check validity */
|
||||
buf = sc->sc_edid + EDID_LENGTH*(i+1);
|
||||
err = tda19988_read_edid_block(sc, buf, i);
|
||||
if (err)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (sc->sc_version == TDA19988)
|
||||
tda19988_reg_set(sc, TDA_TX4, TX4_PD_RAM);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_start(struct tda19988_softc *sc)
|
||||
{
|
||||
device_t dev;
|
||||
uint8_t data;
|
||||
uint16_t ver;
|
||||
|
||||
dev = sc->sc_dev;
|
||||
|
||||
tda19988_cec_write(sc, TDA_CEC_ENAMODS, ENAMODS_RXSENS | ENAMODS_HDMI);
|
||||
DELAY(1000);
|
||||
tda19988_cec_read(sc, TDA_CEC_RXSHPDLEV, &data);
|
||||
|
||||
/* Reset core */
|
||||
tda19988_reg_set(sc, TDA_SOFTRESET, 3);
|
||||
DELAY(100);
|
||||
tda19988_reg_clear(sc, TDA_SOFTRESET, 3);
|
||||
DELAY(100);
|
||||
|
||||
/* reset transmitter: */
|
||||
tda19988_reg_set(sc, TDA_MAIN_CNTRL0, MAIN_CNTRL0_SR);
|
||||
tda19988_reg_clear(sc, TDA_MAIN_CNTRL0, MAIN_CNTRL0_SR);
|
||||
|
||||
/* PLL registers common configuration */
|
||||
tda19988_reg_write(sc, TDA_PLL_SERIAL_1, 0x00);
|
||||
tda19988_reg_write(sc, TDA_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1));
|
||||
tda19988_reg_write(sc, TDA_PLL_SERIAL_3, 0x00);
|
||||
tda19988_reg_write(sc, TDA_SERIALIZER, 0x00);
|
||||
tda19988_reg_write(sc, TDA_BUFFER_OUT, 0x00);
|
||||
tda19988_reg_write(sc, TDA_PLL_SCG1, 0x00);
|
||||
tda19988_reg_write(sc, TDA_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK);
|
||||
tda19988_reg_write(sc, TDA_PLL_SCGN1, 0xfa);
|
||||
tda19988_reg_write(sc, TDA_PLL_SCGN2, 0x00);
|
||||
tda19988_reg_write(sc, TDA_PLL_SCGR1, 0x5b);
|
||||
tda19988_reg_write(sc, TDA_PLL_SCGR2, 0x00);
|
||||
tda19988_reg_write(sc, TDA_PLL_SCG2, 0x10);
|
||||
|
||||
/* Write the default value MUX register */
|
||||
tda19988_reg_write(sc, TDA_MUX_VP_VIP_OUT, 0x24);
|
||||
|
||||
ver = 0;
|
||||
tda19988_reg_read(sc, TDA_VERSION, &data);
|
||||
ver |= data;
|
||||
tda19988_reg_read(sc, TDA_VERSION_MSB, &data);
|
||||
ver |= (data << 8);
|
||||
|
||||
/* Clear feature bits */
|
||||
sc->sc_version = ver & ~0x30;
|
||||
switch (sc->sc_version) {
|
||||
case TDA19988:
|
||||
device_printf(dev, "TDA19988\n");
|
||||
break;
|
||||
default:
|
||||
device_printf(dev, "Unknown device: %04x\n", sc->sc_version);
|
||||
return;
|
||||
}
|
||||
|
||||
tda19988_reg_write(sc, TDA_DDC_CTRL, DDC_ENABLE);
|
||||
tda19988_reg_write(sc, TDA_TX3, 39);
|
||||
|
||||
tda19988_cec_write(sc, TDA_CEC_FRO_IM_CLK_CTRL,
|
||||
CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL);
|
||||
|
||||
/* Default values for RGB 4:4:4 mapping */
|
||||
tda19988_reg_write(sc, TDA_VIP_CNTRL_0, 0x23);
|
||||
tda19988_reg_write(sc, TDA_VIP_CNTRL_1, 0x01);
|
||||
tda19988_reg_write(sc, TDA_VIP_CNTRL_2, 0x45);
|
||||
}
|
||||
|
||||
static enum drm_connector_status
|
||||
tda19988_connector_detect(struct drm_connector *connector, bool force)
|
||||
{
|
||||
struct tda19988_connector *tda_connector = to_tda_connector(connector);
|
||||
struct tda19988_softc * const sc = tda_connector->sc;
|
||||
enum drm_connector_status status;
|
||||
uint8_t data = 0;
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
|
||||
tda19988_cec_read(sc, TDA_CEC_RXSHPDLEV, &data);
|
||||
iic_release_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
|
||||
|
||||
status = (data & RXSHPDLEV_HPD) ?
|
||||
connector_status_connected :
|
||||
connector_status_disconnected;
|
||||
|
||||
/* On connect, invalidate the last EDID */
|
||||
if (status == connector_status_connected &&
|
||||
sc->sc_last_status != connector_status_connected)
|
||||
sc->sc_edid_valid = false;
|
||||
|
||||
sc->sc_last_status = status;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_connector_destroy(struct drm_connector *connector)
|
||||
{
|
||||
drm_connector_unregister(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs tda19988_connector_funcs = {
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.detect = tda19988_connector_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = tda19988_connector_destroy,
|
||||
};
|
||||
|
||||
static int
|
||||
tda19988_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct tda19988_connector *tda_connector = to_tda_connector(connector);
|
||||
struct tda19988_softc * const sc = tda_connector->sc;
|
||||
struct edid *pedid = NULL;
|
||||
int error;
|
||||
|
||||
if (sc->sc_edid_valid) {
|
||||
pedid = (struct edid *)sc->sc_edid;
|
||||
} else {
|
||||
iic_acquire_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
|
||||
if (tda19988_read_edid(sc) == 0)
|
||||
pedid = (struct edid *)sc->sc_edid;
|
||||
iic_release_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
|
||||
sc->sc_edid_valid = true;
|
||||
}
|
||||
|
||||
drm_mode_connector_update_edid_property(connector, pedid);
|
||||
if (pedid == NULL)
|
||||
return 0;
|
||||
|
||||
error = drm_add_edid_modes(connector, pedid);
|
||||
drm_edid_to_eld(connector, pedid);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct drm_encoder *
|
||||
tda19988_connector_best_encoder(struct drm_connector *connector)
|
||||
{
|
||||
int enc_id = connector->encoder_ids[0];
|
||||
struct drm_mode_object *obj;
|
||||
struct drm_encoder *encoder = NULL;
|
||||
|
||||
if (enc_id) {
|
||||
obj = drm_mode_object_find(connector->dev, enc_id,
|
||||
DRM_MODE_OBJECT_ENCODER);
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
encoder = obj_to_encoder(obj);
|
||||
}
|
||||
|
||||
return encoder;
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs tda19988_connector_helper_funcs = {
|
||||
.get_modes = tda19988_connector_get_modes,
|
||||
.best_encoder = tda19988_connector_best_encoder,
|
||||
};
|
||||
|
||||
static int
|
||||
tda19988_bridge_attach(struct drm_bridge *bridge)
|
||||
{
|
||||
struct tda19988_softc *sc = bridge->driver_private;
|
||||
struct tda19988_connector *tda_connector = &sc->sc_connector;
|
||||
struct drm_connector *connector = &tda_connector->base;
|
||||
int error;
|
||||
|
||||
tda_connector->sc = sc;
|
||||
|
||||
connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
|
||||
connector->interlace_allowed = 1;
|
||||
connector->doublescan_allowed = 0;
|
||||
|
||||
drm_connector_init(bridge->dev, connector, &tda19988_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_HDMIA);
|
||||
drm_connector_helper_add(connector, &tda19988_connector_helper_funcs);
|
||||
|
||||
error = drm_mode_connector_attach_encoder(connector, bridge->encoder);
|
||||
if (error != 0)
|
||||
return error;
|
||||
|
||||
return drm_connector_register(connector);
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_bridge_enable(struct drm_bridge *bridge)
|
||||
{
|
||||
struct tda19988_softc * const sc = bridge->driver_private;
|
||||
|
||||
fdtbus_pinctrl_set_config(sc->sc_phandle, "default");
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_bridge_disable(struct drm_bridge *bridge)
|
||||
{
|
||||
struct tda19988_softc * const sc = bridge->driver_private;
|
||||
|
||||
fdtbus_pinctrl_set_config(sc->sc_phandle, "off");
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_bridge_post_disable(struct drm_bridge *bridge)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_bridge_mode_set(struct drm_bridge *bridge,
|
||||
struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct tda19988_softc * const sc = bridge->driver_private;
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
|
||||
tda19988_init_encoder(sc, adjusted_mode);
|
||||
iic_release_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
tda19988_bridge_mode_fixup(struct drm_bridge *bridge,
|
||||
const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs tda19988_bridge_funcs = {
|
||||
.attach = tda19988_bridge_attach,
|
||||
.enable = tda19988_bridge_enable,
|
||||
.pre_enable = tda19988_bridge_pre_enable,
|
||||
.disable = tda19988_bridge_disable,
|
||||
.post_disable = tda19988_bridge_post_disable,
|
||||
.mode_set = tda19988_bridge_mode_set,
|
||||
.mode_fixup = tda19988_bridge_mode_fixup,
|
||||
};
|
||||
|
||||
static int
|
||||
tda19988_ep_activate(device_t dev, struct fdt_endpoint *ep, bool activate)
|
||||
{
|
||||
struct tda19988_softc *sc = device_private(dev);
|
||||
struct fdt_endpoint *in_ep = fdt_endpoint_remote(ep);
|
||||
struct drm_encoder *encoder;
|
||||
int error;
|
||||
|
||||
if (!activate)
|
||||
return EINVAL;
|
||||
|
||||
if (fdt_endpoint_port_index(ep) != TDA19988_PORT_INPUT)
|
||||
return EINVAL;
|
||||
|
||||
switch (fdt_endpoint_type(in_ep)) {
|
||||
case EP_DRM_ENCODER:
|
||||
encoder = fdt_endpoint_get_data(in_ep);
|
||||
break;
|
||||
default:
|
||||
encoder = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (encoder == NULL)
|
||||
return EINVAL;
|
||||
|
||||
sc->sc_bridge.driver_private = sc;
|
||||
sc->sc_bridge.funcs = &tda19988_bridge_funcs;
|
||||
sc->sc_bridge.encoder = encoder;
|
||||
error = drm_bridge_attach(encoder->dev, &sc->sc_bridge);
|
||||
if (error != 0)
|
||||
return EIO;
|
||||
|
||||
encoder->bridge = &sc->sc_bridge;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *
|
||||
tda19988_ep_get_data(device_t dev, struct fdt_endpoint *ep)
|
||||
{
|
||||
struct tda19988_softc *sc = device_private(dev);
|
||||
|
||||
return &sc->sc_bridge;
|
||||
}
|
||||
|
||||
static void
|
||||
tda19988_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct tda19988_softc *sc = device_private(self);
|
||||
struct i2c_attach_args * const ia = aux;
|
||||
const int phandle = ia->ia_cookie;
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_phandle = phandle;
|
||||
sc->sc_i2c = ia->ia_tag;
|
||||
sc->sc_addr = ia->ia_addr;
|
||||
sc->sc_cec_addr = 0x34; /* hardcoded */
|
||||
sc->sc_current_page = 0xff;
|
||||
sc->sc_edid = kmem_zalloc(EDID_LENGTH, KM_SLEEP);
|
||||
sc->sc_edid_len = EDID_LENGTH;
|
||||
sc->sc_edid_valid = false;
|
||||
sc->sc_last_status = connector_status_unknown;
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": NXP TDA19988 HDMI transmitter\n");
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
|
||||
tda19988_start(sc);
|
||||
iic_release_bus(sc->sc_i2c, I2C_F_POLL);
|
||||
|
||||
sc->sc_ports.dp_ep_activate = tda19988_ep_activate;
|
||||
sc->sc_ports.dp_ep_get_data = tda19988_ep_get_data;
|
||||
fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_ENCODER);
|
||||
}
|
||||
|
||||
CFATTACH_DECL_NEW(tdahdmi, sizeof(struct tda19988_softc),
|
||||
tda19988_match, tda19988_attach, NULL, NULL);
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tps65217pmic.c,v 1.12 2018/06/16 21:22:13 thorpej Exp $ */
|
||||
/* $NetBSD: tps65217pmic.c,v 1.12.8.1 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2013 The NetBSD Foundation, Inc.
|
||||
|
@ -34,8 +34,10 @@
|
|||
* TODO: battery, sequencer, pgood
|
||||
*/
|
||||
|
||||
#include "opt_fdt.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.12 2018/06/16 21:22:13 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.12.8.1 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -47,20 +49,28 @@ __KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.12 2018/06/16 21:22:13 thorpej Ex
|
|||
#include <dev/i2c/i2cvar.h>
|
||||
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
#include <dev/sysmon/sysmon_taskq.h>
|
||||
|
||||
#include <dev/i2c/tps65217pmicreg.h>
|
||||
#include <dev/i2c/tps65217pmicvar.h>
|
||||
|
||||
#ifdef FDT
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
#endif
|
||||
|
||||
#define NTPS_REG 7
|
||||
#define SNUM_REGS NTPS_REG-1
|
||||
#define SNUM_USBSTATUS NTPS_REG
|
||||
#define SNUM_ACSTATUS NTPS_REG+1
|
||||
|
||||
struct tps_reg_param;
|
||||
|
||||
struct tps65217pmic_softc {
|
||||
device_t sc_dev;
|
||||
|
||||
i2c_tag_t sc_tag;
|
||||
i2c_addr_t sc_addr;
|
||||
int sc_phandle;
|
||||
|
||||
uint8_t sc_version;
|
||||
uint8_t sc_revision;
|
||||
|
@ -83,6 +93,17 @@ struct tps65217pmic_softc {
|
|||
struct sysmon_pswitch sc_smpsw;
|
||||
};
|
||||
|
||||
struct tps65217reg_softc {
|
||||
device_t sc_dev;
|
||||
int sc_phandle;
|
||||
struct tps_reg_param *sc_param;
|
||||
};
|
||||
|
||||
struct tps65217reg_attach_args {
|
||||
struct tps_reg_param *reg_param;
|
||||
int reg_phandle;
|
||||
};
|
||||
|
||||
/* Voltage regulators */
|
||||
enum tps_reg_num {
|
||||
TPS65217PMIC_LDO1,
|
||||
|
@ -159,6 +180,10 @@ static void tps65217pmic_wled_init(struct tps65217pmic_softc *, int, int, int);
|
|||
CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
|
||||
tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
|
||||
|
||||
#ifdef FDT
|
||||
static void tps65217pmic_regulator_attach(struct tps65217pmic_softc *);
|
||||
#endif
|
||||
|
||||
/* Possible settings of LDO1 in mV. */
|
||||
static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350,
|
||||
1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 };
|
||||
|
@ -177,7 +202,7 @@ static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750,
|
|||
|
||||
static struct tps_reg_param tps_regulators[] = {
|
||||
{
|
||||
.name = "LDO1",
|
||||
.name = "ldo1",
|
||||
.voltage_min = 1000,
|
||||
.voltage_max = 3300,
|
||||
.voltages = ldo1voltages,
|
||||
|
@ -190,7 +215,7 @@ static struct tps_reg_param tps_regulators[] = {
|
|||
.enable_bit = TPS65217PMIC_ENABLE_LDO1
|
||||
},
|
||||
{
|
||||
.name = "LDO2",
|
||||
.name = "ldo2",
|
||||
.voltage_min = 900,
|
||||
.voltage_max = 3300,
|
||||
.voltages = ldo2voltages,
|
||||
|
@ -203,7 +228,7 @@ static struct tps_reg_param tps_regulators[] = {
|
|||
.enable_bit = TPS65217PMIC_ENABLE_LDO2
|
||||
},
|
||||
{
|
||||
.name = "LDO3",
|
||||
.name = "ldo3",
|
||||
.voltage_min = 1500,
|
||||
.voltage_max = 3300,
|
||||
.voltages = ldo3voltages,
|
||||
|
@ -216,7 +241,7 @@ static struct tps_reg_param tps_regulators[] = {
|
|||
.enable_bit = TPS65217PMIC_ENABLE_LDO3
|
||||
},
|
||||
{
|
||||
.name = "LDO4",
|
||||
.name = "ldo4",
|
||||
.voltage_min = 1500,
|
||||
.voltage_max = 3300,
|
||||
.voltages = ldo3voltages,
|
||||
|
@ -229,7 +254,7 @@ static struct tps_reg_param tps_regulators[] = {
|
|||
.enable_bit = TPS65217PMIC_ENABLE_LDO4
|
||||
},
|
||||
{
|
||||
.name = "DCDC1",
|
||||
.name = "dcdc1",
|
||||
.voltage_min = 900,
|
||||
.voltage_max = 3300,
|
||||
.voltages = ldo2voltages,
|
||||
|
@ -242,7 +267,7 @@ static struct tps_reg_param tps_regulators[] = {
|
|||
.enable_bit = TPS65217PMIC_ENABLE_DCDC1
|
||||
},
|
||||
{
|
||||
.name = "DCDC2",
|
||||
.name = "dcdc2",
|
||||
.voltage_min = 900,
|
||||
.voltage_max = 3300,
|
||||
.voltages = ldo2voltages,
|
||||
|
@ -255,7 +280,7 @@ static struct tps_reg_param tps_regulators[] = {
|
|||
.enable_bit = TPS65217PMIC_ENABLE_DCDC2
|
||||
},
|
||||
{
|
||||
.name = "DCDC3",
|
||||
.name = "dcdc3",
|
||||
.voltage_min = 900,
|
||||
.voltage_max = 3300,
|
||||
.voltages = ldo2voltages,
|
||||
|
@ -271,10 +296,19 @@ static struct tps_reg_param tps_regulators[] = {
|
|||
|
||||
static bool matched = false;
|
||||
|
||||
static const struct device_compatible_entry compat_data[] = {
|
||||
{ "ti,tps65217", 0 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static int
|
||||
tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
|
||||
{
|
||||
struct i2c_attach_args *ia = aux;
|
||||
int match_result;
|
||||
|
||||
if (iic_use_direct_match(ia, cf, compat_data, &match_result))
|
||||
return match_result;
|
||||
|
||||
if (ia->ia_addr == TPS65217PMIC_ADDR) {
|
||||
/* we can only have one */
|
||||
|
@ -299,6 +333,7 @@ tps65217pmic_attach(device_t parent, device_t self, void *aux)
|
|||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_addr = ia->ia_addr;
|
||||
sc->sc_phandle = ia->ia_cookie;
|
||||
sc->sc_tag = ia->ia_tag;
|
||||
|
||||
dict = device_properties(self);
|
||||
|
@ -349,6 +384,10 @@ tps65217pmic_attach(device_t parent, device_t self, void *aux)
|
|||
tps65217pmic_wled_init(sc, isel, fdim, brightness);
|
||||
|
||||
tps65217pmic_envsys_register(sc);
|
||||
|
||||
#ifdef FDT
|
||||
tps65217pmic_regulator_attach(sc);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -381,7 +420,7 @@ tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc)
|
|||
}
|
||||
|
||||
static void
|
||||
tps65217pmic_power_monitor(void *aux)
|
||||
tps65217pmic_power_monitor_task(void *aux)
|
||||
{
|
||||
struct tps65217pmic_softc *sc;
|
||||
uint8_t status;
|
||||
|
@ -423,6 +462,12 @@ tps65217pmic_power_monitor(void *aux)
|
|||
callout_schedule(&sc->sc_powerpollco, hz);
|
||||
}
|
||||
|
||||
static void
|
||||
tps65217pmic_power_monitor(void *aux)
|
||||
{
|
||||
sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux);
|
||||
}
|
||||
|
||||
static void
|
||||
tps65217pmic_wled_init(struct tps65217pmic_softc *sc, int isel, int fdim,
|
||||
int brightness)
|
||||
|
@ -835,5 +880,160 @@ tps65217pmic_set_volt(device_t self, const char *name, int mvolt)
|
|||
while (val & TPS65217PMIC_DEFSLEW_GO) {
|
||||
val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
|
||||
}
|
||||
|
||||
regulator->current_voltage = regulator->voltages[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef FDT
|
||||
static struct tps_reg_param *
|
||||
tps65217pmic_get_params(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < __arraycount(tps_regulators); i++) {
|
||||
if (strcmp(name, tps_regulators[i].name) == 0)
|
||||
return &tps_regulators[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
tps65217pmic_regulator_attach(struct tps65217pmic_softc *sc)
|
||||
{
|
||||
struct tps65217reg_attach_args raa;
|
||||
struct tps_reg_param *param;
|
||||
const char *compat_name;
|
||||
int phandle, child;
|
||||
|
||||
phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
|
||||
if (phandle <= 0)
|
||||
return;
|
||||
|
||||
for (child = OF_child(phandle); child; child = OF_peer(child)) {
|
||||
compat_name = fdtbus_get_string(child, "regulator-compatible");
|
||||
if (compat_name == NULL)
|
||||
continue;
|
||||
param = tps65217pmic_get_params(compat_name);
|
||||
if (param == NULL)
|
||||
continue;
|
||||
|
||||
raa.reg_param = param;
|
||||
raa.reg_phandle = child;
|
||||
config_found(sc->sc_dev, &raa, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tps65217reg_acquire(device_t dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tps65217reg_release(device_t dev)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
tps65217reg_enable(device_t dev, bool enable)
|
||||
{
|
||||
struct tps65217reg_softc *sc = device_private(dev);
|
||||
struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
|
||||
struct tps_reg_param *regulator = sc->sc_param;
|
||||
uint8_t val;
|
||||
int error;
|
||||
|
||||
error = iic_acquire_bus(pmic_sc->sc_tag, I2C_F_POLL);
|
||||
if (error != 0)
|
||||
return error;
|
||||
|
||||
val = tps65217pmic_reg_read(pmic_sc, TPS65217PMIC_ENABLE);
|
||||
if (enable)
|
||||
val |= regulator->enable_bit;
|
||||
else
|
||||
val &= ~regulator->enable_bit;
|
||||
tps65217pmic_reg_write(pmic_sc, TPS65217PMIC_ENABLE, val);
|
||||
|
||||
regulator->is_enabled = enable;
|
||||
|
||||
iic_release_bus(pmic_sc->sc_tag, I2C_F_POLL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tps65217reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
|
||||
{
|
||||
struct tps65217reg_softc *sc = device_private(dev);
|
||||
struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
|
||||
struct tps_reg_param *regulator = sc->sc_param;
|
||||
int error;
|
||||
|
||||
error = iic_acquire_bus(pmic_sc->sc_tag, I2C_F_POLL);
|
||||
if (error != 0)
|
||||
return error;
|
||||
|
||||
error = tps65217pmic_set_volt(pmic_sc->sc_dev, regulator->name, min_uvol / 1000);
|
||||
|
||||
iic_release_bus(pmic_sc->sc_tag, I2C_F_POLL);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
tps65217reg_get_voltage(device_t dev, u_int *puvol)
|
||||
{
|
||||
struct tps65217reg_softc *sc = device_private(dev);
|
||||
struct tps_reg_param *regulator = sc->sc_param;
|
||||
|
||||
*puvol = (u_int)regulator->current_voltage * 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fdtbus_regulator_controller_func tps65217reg_funcs = {
|
||||
.acquire = tps65217reg_acquire,
|
||||
.release = tps65217reg_release,
|
||||
.enable = tps65217reg_enable,
|
||||
.set_voltage = tps65217reg_set_voltage,
|
||||
.get_voltage = tps65217reg_get_voltage,
|
||||
};
|
||||
|
||||
static int
|
||||
tps65217reg_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
tps65217reg_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct tps65217reg_softc *sc = device_private(self);
|
||||
struct tps65217reg_attach_args *raa = aux;
|
||||
const char *regname;
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_phandle = raa->reg_phandle;
|
||||
sc->sc_param = raa->reg_param;
|
||||
|
||||
fdtbus_register_regulator_controller(self, sc->sc_phandle,
|
||||
&tps65217reg_funcs);
|
||||
|
||||
regname = fdtbus_get_string(sc->sc_phandle, "regulator-name");
|
||||
if (regname == NULL)
|
||||
regname = fdtbus_get_string(sc->sc_phandle, "regulator-compatible");
|
||||
|
||||
aprint_naive("\n");
|
||||
if (regname != NULL)
|
||||
aprint_normal(": %s\n", regname);
|
||||
else
|
||||
aprint_normal("\n");
|
||||
}
|
||||
|
||||
CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc),
|
||||
tps65217reg_match, tps65217reg_attach, NULL, NULL);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,449 +0,0 @@
|
|||
/* $NetBSD: tps65950.c,v 1.6 2018/06/16 21:22:13 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2012 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 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TI TPS65950 OMAP Power Management and System Companion Device
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tps65950.c,v 1.6 2018/06/16 21:22:13 thorpej Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/wdog.h>
|
||||
|
||||
#include <dev/i2c/i2cvar.h>
|
||||
|
||||
#include <dev/clock_subr.h>
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
|
||||
/* Default watchdog period, in seconds */
|
||||
#ifndef TPS65950_WDOG_DEFAULT_PERIOD
|
||||
#define TPS65950_WDOG_DEFAULT_PERIOD 30
|
||||
#endif
|
||||
|
||||
/* I2C Bus Addressing */
|
||||
#define TPS65950_ADDR_ID1 0x48 /* GP */
|
||||
#define TPS65950_ADDR_ID2 0x49 /* GP */
|
||||
#define TPS65950_ADDR_ID3 0x4a /* GP */
|
||||
#define TPS65950_ADDR_ID4 0x4b /* GP */
|
||||
#define TPS65950_ADDR_ID5 0x12 /* SmartReflex */
|
||||
|
||||
/* ID2 */
|
||||
#define TPS65950_ID2_IDCODE_7_0 0x85
|
||||
#define TPS65950_ID2_IDCODE_15_8 0x86
|
||||
#define TPS65950_ID2_IDCODE_23_16 0x87
|
||||
#define TPS65950_ID2_IDCODE_31_24 0x88
|
||||
#define TPS65950_ID2_UNLOCK_TEST_REG 0x97
|
||||
#define TPS65950_ID2_UNLOCK_TEST_REG_MAGIC 0x49
|
||||
|
||||
/* ID3 */
|
||||
#define TPS65950_LED_BASE 0xee
|
||||
#define TPS65950_ID3_REG_LED (TPS65950_LED_BASE + 0)
|
||||
#define TPS65950_ID3_REG_LED_LEDAON __BIT(0)
|
||||
#define TPS65950_ID3_REG_LED_LEDBON __BIT(1)
|
||||
#define TPS65950_ID3_REG_LED_LEDAPWM __BIT(4)
|
||||
#define TPS65950_ID3_REG_LED_LEDBPWM __BIT(5)
|
||||
|
||||
/* ID4 */
|
||||
#define TPS65950_PM_RECEIVER_BASE 0x5b
|
||||
#define TPS65950_ID4_REG_WATCHDOG_CFG (TPS65950_PM_RECEIVER_BASE + 3)
|
||||
#define TPS65950_RTC_BASE 0x1c
|
||||
#define TPS65950_ID4_REG_SECONDS_REG (TPS65950_RTC_BASE + 0)
|
||||
#define TPS65950_ID4_REG_MINUTES_REG (TPS65950_RTC_BASE + 1)
|
||||
#define TPS65950_ID4_REG_HOURS_REG (TPS65950_RTC_BASE + 2)
|
||||
#define TPS65950_ID4_REG_DAYS_REG (TPS65950_RTC_BASE + 3)
|
||||
#define TPS65950_ID4_REG_MONTHS_REG (TPS65950_RTC_BASE + 4)
|
||||
#define TPS65950_ID4_REG_YEARS_REG (TPS65950_RTC_BASE + 5)
|
||||
#define TPS65950_ID4_REG_WEEKS_REG (TPS65950_RTC_BASE + 6)
|
||||
#define TPS65950_ID4_REG_RTC_CTRL_REG (TPS65950_RTC_BASE + 13)
|
||||
#define TPS65950_ID4_REG_RTC_CTRL_REG_GET_TIME __BIT(6)
|
||||
#define TPS65950_ID4_REG_RTC_CTRL_REG_STOP_RTC __BIT(1)
|
||||
|
||||
struct tps65950_softc {
|
||||
device_t sc_dev;
|
||||
i2c_tag_t sc_i2c;
|
||||
i2c_addr_t sc_addr;
|
||||
|
||||
struct sysctllog *sc_sysctllog;
|
||||
struct sysmon_wdog sc_smw;
|
||||
struct todr_chip_handle sc_todr;
|
||||
};
|
||||
|
||||
static int tps65950_match(device_t, cfdata_t, void *);
|
||||
static void tps65950_attach(device_t, device_t, void *);
|
||||
|
||||
static int tps65950_read_1(struct tps65950_softc *, uint8_t, uint8_t *);
|
||||
static int tps65950_write_1(struct tps65950_softc *, uint8_t, uint8_t);
|
||||
|
||||
static void tps65950_sysctl_attach(struct tps65950_softc *);
|
||||
|
||||
static void tps65950_rtc_attach(struct tps65950_softc *);
|
||||
static int tps65950_rtc_enable(struct tps65950_softc *, bool);
|
||||
static int tps65950_rtc_gettime(todr_chip_handle_t, struct clock_ymdhms *);
|
||||
static int tps65950_rtc_settime(todr_chip_handle_t, struct clock_ymdhms *);
|
||||
|
||||
static void tps65950_wdog_attach(struct tps65950_softc *);
|
||||
static int tps65950_wdog_setmode(struct sysmon_wdog *);
|
||||
static int tps65950_wdog_tickle(struct sysmon_wdog *);
|
||||
|
||||
CFATTACH_DECL_NEW(tps65950pm, sizeof(struct tps65950_softc),
|
||||
tps65950_match, tps65950_attach, NULL, NULL);
|
||||
|
||||
static int
|
||||
tps65950_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct i2c_attach_args *ia = aux;
|
||||
|
||||
switch (ia->ia_addr) {
|
||||
case TPS65950_ADDR_ID1:
|
||||
case TPS65950_ADDR_ID2:
|
||||
case TPS65950_ADDR_ID3:
|
||||
case TPS65950_ADDR_ID4:
|
||||
case TPS65950_ADDR_ID5:
|
||||
return I2C_MATCH_ADDRESS_ONLY;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tps65950_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct tps65950_softc *sc = device_private(self);
|
||||
struct i2c_attach_args *ia = aux;
|
||||
uint8_t buf[4];
|
||||
uint32_t idcode;
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_i2c = ia->ia_tag;
|
||||
sc->sc_addr = ia->ia_addr;
|
||||
|
||||
aprint_naive("\n");
|
||||
|
||||
switch (sc->sc_addr) {
|
||||
case TPS65950_ADDR_ID2:
|
||||
memset(buf, 0, sizeof(buf));
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
tps65950_write_1(sc, TPS65950_ID2_UNLOCK_TEST_REG,
|
||||
TPS65950_ID2_UNLOCK_TEST_REG_MAGIC);
|
||||
tps65950_read_1(sc, TPS65950_ID2_IDCODE_7_0, &buf[0]);
|
||||
tps65950_read_1(sc, TPS65950_ID2_IDCODE_15_8, &buf[1]);
|
||||
tps65950_read_1(sc, TPS65950_ID2_IDCODE_23_16, &buf[2]);
|
||||
tps65950_read_1(sc, TPS65950_ID2_IDCODE_31_24, &buf[3]);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
idcode = (buf[0] << 0) | (buf[1] << 8) |
|
||||
(buf[2] << 16) | (buf[3] << 24);
|
||||
aprint_normal(": IDCODE %08X\n", idcode);
|
||||
break;
|
||||
case TPS65950_ADDR_ID3:
|
||||
aprint_normal(": LED\n");
|
||||
tps65950_sysctl_attach(sc);
|
||||
break;
|
||||
case TPS65950_ADDR_ID4:
|
||||
aprint_normal(": RTC, WATCHDOG\n");
|
||||
tps65950_rtc_attach(sc);
|
||||
tps65950_wdog_attach(sc);
|
||||
break;
|
||||
default:
|
||||
aprint_normal("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tps65950_read_1(struct tps65950_softc *sc, uint8_t reg, uint8_t *val)
|
||||
{
|
||||
return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr,
|
||||
®, sizeof(reg), val, sizeof(*val), 0);
|
||||
}
|
||||
|
||||
static int
|
||||
tps65950_write_1(struct tps65950_softc *sc, uint8_t reg, uint8_t val)
|
||||
{
|
||||
uint8_t data[2] = { reg, val };
|
||||
return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr,
|
||||
NULL, 0, data, sizeof(data), 0);
|
||||
}
|
||||
|
||||
static int
|
||||
tps65950_sysctl_leda(SYSCTLFN_ARGS)
|
||||
{
|
||||
struct tps65950_softc *sc;
|
||||
struct sysctlnode node;
|
||||
uint8_t val;
|
||||
u_int leda;
|
||||
int error;
|
||||
|
||||
node = *rnode;
|
||||
sc = node.sysctl_data;
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
error = tps65950_read_1(sc, TPS65950_ID3_REG_LED, &val);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
if (error)
|
||||
return error;
|
||||
leda = (val & TPS65950_ID3_REG_LED_LEDAON) ? 1 : 0;
|
||||
node.sysctl_data = &leda;
|
||||
error = sysctl_lookup(SYSCTLFN_CALL(&node));
|
||||
if (error || newp == NULL)
|
||||
return error;
|
||||
|
||||
if (leda)
|
||||
val |= (TPS65950_ID3_REG_LED_LEDAON|TPS65950_ID3_REG_LED_LEDAPWM);
|
||||
else
|
||||
val &= ~(TPS65950_ID3_REG_LED_LEDAON|TPS65950_ID3_REG_LED_LEDAPWM);
|
||||
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
error = tps65950_write_1(sc, TPS65950_ID3_REG_LED, val);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
tps65950_sysctl_ledb(SYSCTLFN_ARGS)
|
||||
{
|
||||
struct tps65950_softc *sc;
|
||||
struct sysctlnode node;
|
||||
uint8_t val;
|
||||
u_int ledb;
|
||||
int error;
|
||||
|
||||
node = *rnode;
|
||||
sc = node.sysctl_data;
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
error = tps65950_read_1(sc, TPS65950_ID3_REG_LED, &val);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
if (error)
|
||||
return error;
|
||||
ledb = (val & TPS65950_ID3_REG_LED_LEDBON) ? 1 : 0;
|
||||
node.sysctl_data = &ledb;
|
||||
error = sysctl_lookup(SYSCTLFN_CALL(&node));
|
||||
if (error || newp == NULL)
|
||||
return error;
|
||||
|
||||
if (ledb)
|
||||
val |= (TPS65950_ID3_REG_LED_LEDBON|TPS65950_ID3_REG_LED_LEDBPWM);
|
||||
else
|
||||
val &= ~(TPS65950_ID3_REG_LED_LEDBON|TPS65950_ID3_REG_LED_LEDBPWM);
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
error = tps65950_write_1(sc, TPS65950_ID3_REG_LED, val);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static void
|
||||
tps65950_sysctl_attach(struct tps65950_softc *sc)
|
||||
{
|
||||
struct sysctllog **log = &sc->sc_sysctllog;
|
||||
const struct sysctlnode *rnode, *cnode;
|
||||
int error;
|
||||
|
||||
error = sysctl_createv(log, 0, NULL, &rnode, CTLFLAG_PERMANENT,
|
||||
CTLTYPE_NODE, "tps65950", SYSCTL_DESCR("tps65950 control"),
|
||||
NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
|
||||
if (error)
|
||||
return;
|
||||
|
||||
error = sysctl_createv(log, 0, &rnode, &cnode,
|
||||
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "leda",
|
||||
SYSCTL_DESCR("LEDA enable"), tps65950_sysctl_leda, 0,
|
||||
(void *)sc, 0, CTL_CREATE, CTL_EOL);
|
||||
if (error)
|
||||
return;
|
||||
|
||||
error = sysctl_createv(log, 0, &rnode, &cnode,
|
||||
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, "ledb",
|
||||
SYSCTL_DESCR("LEDB enable"), tps65950_sysctl_ledb, 0,
|
||||
(void *)sc, 0, CTL_CREATE, CTL_EOL);
|
||||
if (error)
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
tps65950_rtc_attach(struct tps65950_softc *sc)
|
||||
{
|
||||
sc->sc_todr.todr_gettime_ymdhms = tps65950_rtc_gettime;
|
||||
sc->sc_todr.todr_settime_ymdhms = tps65950_rtc_settime;
|
||||
sc->sc_todr.cookie = sc;
|
||||
todr_attach(&sc->sc_todr);
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
tps65950_rtc_enable(sc, true);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
tps65950_rtc_enable(struct tps65950_softc *sc, bool enable)
|
||||
{
|
||||
uint8_t rtc_ctrl;
|
||||
int error;
|
||||
|
||||
error = tps65950_read_1(sc, TPS65950_ID4_REG_RTC_CTRL_REG, &rtc_ctrl);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (enable) {
|
||||
rtc_ctrl |= TPS65950_ID4_REG_RTC_CTRL_REG_STOP_RTC;
|
||||
} else {
|
||||
rtc_ctrl &= ~TPS65950_ID4_REG_RTC_CTRL_REG_STOP_RTC;
|
||||
}
|
||||
|
||||
return tps65950_write_1(sc, TPS65950_ID4_REG_RTC_CTRL_REG, rtc_ctrl);
|
||||
}
|
||||
|
||||
#define RTC_READ(reg, var) \
|
||||
do { \
|
||||
tps65950_write_1(sc, TPS65950_ID4_REG_RTC_CTRL_REG, \
|
||||
TPS65950_ID4_REG_RTC_CTRL_REG_GET_TIME); \
|
||||
if ((error = tps65950_read_1(sc, (reg), &(var))) != 0) { \
|
||||
iic_release_bus(sc->sc_i2c, 0); \
|
||||
return error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RTC_WRITE(reg, val) \
|
||||
do { \
|
||||
if ((error = tps65950_write_1(sc, (reg), (val))) != 0) { \
|
||||
iic_release_bus(sc->sc_i2c, 0); \
|
||||
return error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
tps65950_rtc_gettime(todr_chip_handle_t tch, struct clock_ymdhms *dt)
|
||||
{
|
||||
struct tps65950_softc *sc = tch->cookie;
|
||||
uint8_t seconds_reg, minutes_reg, hours_reg,
|
||||
days_reg, months_reg, years_reg, weeks_reg;
|
||||
int error = 0;
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
RTC_READ(TPS65950_ID4_REG_SECONDS_REG, seconds_reg);
|
||||
RTC_READ(TPS65950_ID4_REG_MINUTES_REG, minutes_reg);
|
||||
RTC_READ(TPS65950_ID4_REG_HOURS_REG, hours_reg);
|
||||
RTC_READ(TPS65950_ID4_REG_DAYS_REG, days_reg);
|
||||
RTC_READ(TPS65950_ID4_REG_MONTHS_REG, months_reg);
|
||||
RTC_READ(TPS65950_ID4_REG_YEARS_REG, years_reg);
|
||||
RTC_READ(TPS65950_ID4_REG_WEEKS_REG, weeks_reg);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
|
||||
dt->dt_sec = bcdtobin(seconds_reg);
|
||||
dt->dt_min = bcdtobin(minutes_reg);
|
||||
dt->dt_hour = bcdtobin(hours_reg);
|
||||
dt->dt_day = bcdtobin(days_reg);
|
||||
dt->dt_mon = bcdtobin(months_reg);
|
||||
dt->dt_year = bcdtobin(years_reg) + 2000;
|
||||
dt->dt_wday = bcdtobin(weeks_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tps65950_rtc_settime(todr_chip_handle_t tch, struct clock_ymdhms *dt)
|
||||
{
|
||||
struct tps65950_softc *sc = tch->cookie;
|
||||
int error = 0;
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
tps65950_rtc_enable(sc, false);
|
||||
RTC_WRITE(TPS65950_ID4_REG_SECONDS_REG, bintobcd(dt->dt_sec));
|
||||
RTC_WRITE(TPS65950_ID4_REG_MINUTES_REG, bintobcd(dt->dt_min));
|
||||
RTC_WRITE(TPS65950_ID4_REG_HOURS_REG, bintobcd(dt->dt_hour));
|
||||
RTC_WRITE(TPS65950_ID4_REG_DAYS_REG, bintobcd(dt->dt_day));
|
||||
RTC_WRITE(TPS65950_ID4_REG_MONTHS_REG, bintobcd(dt->dt_mon));
|
||||
RTC_WRITE(TPS65950_ID4_REG_YEARS_REG, bintobcd(dt->dt_year % 100));
|
||||
RTC_WRITE(TPS65950_ID4_REG_WEEKS_REG, bintobcd(dt->dt_wday));
|
||||
tps65950_rtc_enable(sc, true);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static void
|
||||
tps65950_wdog_attach(struct tps65950_softc *sc)
|
||||
{
|
||||
sc->sc_smw.smw_name = device_xname(sc->sc_dev);
|
||||
sc->sc_smw.smw_cookie = sc;
|
||||
sc->sc_smw.smw_setmode = tps65950_wdog_setmode;
|
||||
sc->sc_smw.smw_tickle = tps65950_wdog_tickle;
|
||||
sc->sc_smw.smw_period = TPS65950_WDOG_DEFAULT_PERIOD;
|
||||
|
||||
if (sysmon_wdog_register(&sc->sc_smw) != 0)
|
||||
aprint_error_dev(sc->sc_dev, "couldn't register watchdog\n");
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
tps65950_write_1(sc, TPS65950_ID4_REG_WATCHDOG_CFG, 0);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
tps65950_wdog_setmode(struct sysmon_wdog *smw)
|
||||
{
|
||||
struct tps65950_softc *sc = smw->smw_cookie;
|
||||
int error;
|
||||
|
||||
if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
error = tps65950_write_1(sc, TPS65950_ID4_REG_WATCHDOG_CFG, 0);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
} else {
|
||||
if (smw->smw_period == WDOG_PERIOD_DEFAULT) {
|
||||
smw->smw_period = TPS65950_WDOG_DEFAULT_PERIOD;
|
||||
}
|
||||
if (smw->smw_period > 30) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
error = tps65950_wdog_tickle(smw);
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
tps65950_wdog_tickle(struct sysmon_wdog *smw)
|
||||
{
|
||||
struct tps65950_softc *sc = smw->smw_cookie;
|
||||
int error;
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, 0);
|
||||
tps65950_write_1(sc, TPS65950_ID4_REG_WATCHDOG_CFG, 0);
|
||||
error = tps65950_write_1(sc, TPS65950_ID4_REG_WATCHDOG_CFG,
|
||||
smw->smw_period + 1);
|
||||
iic_release_bus(sc->sc_i2c, 0);
|
||||
|
||||
return error;
|
||||
}
|
|
@ -0,0 +1,411 @@
|
|||
/* $NetBSD: twl4030.c,v 1.3.2.2 2019/11/27 13:46:45 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 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 "opt_fdt.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: twl4030.c,v 1.3.2.2 2019/11/27 13:46:45 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/gpio.h>
|
||||
|
||||
#include <dev/i2c/i2cvar.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#define TWL_PIN_COUNT 16
|
||||
|
||||
/* TWL4030 is a multi-function IC. Each module is at a separate I2C address */
|
||||
#define ADDR_USB 0x00
|
||||
#define ADDR_INT 0x01
|
||||
#define ADDR_AUX 0x02
|
||||
#define ADDR_POWER 0x03
|
||||
|
||||
/* INTBR registers */
|
||||
#define IDCODE_7_0 0x85
|
||||
#define IDCODE_15_8 0x86
|
||||
#define IDCODE_23_16 0x87
|
||||
#define IDCODE_31_24 0x88
|
||||
|
||||
/* GPIO registers */
|
||||
#define GPIOBASE 0x98
|
||||
#define GPIODATAIN(pin) (GPIOBASE + 0x00 + (pin) / 8)
|
||||
#define GPIODATADIR(pin) (GPIOBASE + 0x03 + (pin) / 8)
|
||||
#define CLEARGPIODATAOUT(pin) (GPIOBASE + 0x09 + (pin) / 8)
|
||||
#define SETGPIODATAOUT(pin) (GPIOBASE + 0x0c + (pin) / 8)
|
||||
#define PIN_BIT(pin) __BIT((pin) % 8)
|
||||
#define GPIOPUPDCTR(pin) (GPIOBASE + 0x13 + (n) / 4)
|
||||
#define PUPD_BITS(pin) __BITS((pin) % 4 + 1, (pin) % 4)
|
||||
|
||||
/* POWER registers */
|
||||
#define SECONDS_REG 0x1c
|
||||
#define MINUTES_REG 0x1d
|
||||
#define HOURS_REG 0x1e
|
||||
#define DAYS_REG 0x1f
|
||||
#define MONTHS_REG 0x20
|
||||
#define YEARS_REG 0x21
|
||||
#define WEEKS_REG 0x22
|
||||
#define RTC_CTRL_REG 0x29
|
||||
#define GET_TIME __BIT(6)
|
||||
#define STOP_RTC __BIT(0)
|
||||
|
||||
struct twl_softc {
|
||||
device_t sc_dev;
|
||||
i2c_tag_t sc_i2c;
|
||||
i2c_addr_t sc_addr;
|
||||
int sc_phandle;
|
||||
|
||||
int sc_npins;
|
||||
|
||||
struct todr_chip_handle sc_todr;
|
||||
};
|
||||
|
||||
struct twl_pin {
|
||||
struct twl_softc *pin_sc;
|
||||
int pin_num;
|
||||
int pin_flags;
|
||||
bool pin_actlo;
|
||||
};
|
||||
|
||||
static const struct device_compatible_entry compat_data[] = {
|
||||
{ "ti,twl4030", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
#ifdef FDT
|
||||
static const char * const rtc_compatible[] = { "ti,twl4030-rtc", NULL };
|
||||
static const char * const gpio_compatible[] = { "ti,twl4030-gpio", NULL };
|
||||
#endif
|
||||
|
||||
static uint8_t
|
||||
twl_read(struct twl_softc *sc, uint8_t mod, uint8_t reg, int flags)
|
||||
{
|
||||
uint8_t val = 0;
|
||||
int error;
|
||||
|
||||
error = iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr + mod,
|
||||
®, 1, &val, 1, flags);
|
||||
if (error != 0)
|
||||
aprint_error_dev(sc->sc_dev, "error reading reg %#x: %d\n", reg, error);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void
|
||||
twl_write(struct twl_softc *sc, uint8_t mod, uint8_t reg, uint8_t val, int flags)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
int error;
|
||||
|
||||
buf[0] = reg;
|
||||
buf[1] = val;
|
||||
|
||||
error = iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr + mod,
|
||||
NULL, 0, buf, 2, flags);
|
||||
if (error != 0)
|
||||
aprint_error_dev(sc->sc_dev, "error writing reg %#x: %d\n", reg, error);
|
||||
}
|
||||
|
||||
#define I2C_LOCK(sc) iic_acquire_bus((sc)->sc_i2c, I2C_F_POLL)
|
||||
#define I2C_UNLOCK(sc) iic_release_bus((sc)->sc_i2c, I2C_F_POLL)
|
||||
|
||||
#define INT_READ(sc, reg) twl_read((sc), ADDR_INT, (reg), I2C_F_POLL)
|
||||
#define INT_WRITE(sc, reg, val) twl_write((sc), ADDR_INT, (reg), (val), I2C_F_POLL)
|
||||
|
||||
#define POWER_READ(sc, reg) twl_read((sc), ADDR_POWER, (reg), I2C_F_POLL)
|
||||
#define POWER_WRITE(sc, reg, val) twl_write((sc), ADDR_POWER, (reg), (val), I2C_F_POLL)
|
||||
|
||||
static void
|
||||
twl_rtc_enable(struct twl_softc *sc, bool onoff)
|
||||
{
|
||||
uint8_t rtc_ctrl;
|
||||
|
||||
rtc_ctrl = POWER_READ(sc, RTC_CTRL_REG);
|
||||
if (onoff)
|
||||
rtc_ctrl |= STOP_RTC; /* 1: RTC is running */
|
||||
else
|
||||
rtc_ctrl &= ~STOP_RTC; /* 0: RTC is frozen */
|
||||
POWER_WRITE(sc, RTC_CTRL_REG, rtc_ctrl);
|
||||
}
|
||||
|
||||
static int
|
||||
twl_rtc_gettime(todr_chip_handle_t tch, struct clock_ymdhms *dt)
|
||||
{
|
||||
struct twl_softc *sc = tch->cookie;
|
||||
uint8_t seconds_reg, minutes_reg, hours_reg,
|
||||
days_reg, months_reg, years_reg, weeks_reg;
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
|
||||
seconds_reg = POWER_READ(sc, SECONDS_REG);
|
||||
minutes_reg = POWER_READ(sc, MINUTES_REG);
|
||||
hours_reg = POWER_READ(sc, HOURS_REG);
|
||||
days_reg = POWER_READ(sc, DAYS_REG);
|
||||
months_reg = POWER_READ(sc, MONTHS_REG);
|
||||
years_reg = POWER_READ(sc, YEARS_REG);
|
||||
weeks_reg = POWER_READ(sc, WEEKS_REG);
|
||||
iic_release_bus(sc->sc_i2c, I2C_F_POLL);
|
||||
|
||||
dt->dt_sec = bcdtobin(seconds_reg);
|
||||
dt->dt_min = bcdtobin(minutes_reg);
|
||||
dt->dt_hour = bcdtobin(hours_reg);
|
||||
dt->dt_day = bcdtobin(days_reg);
|
||||
dt->dt_mon = bcdtobin(months_reg);
|
||||
dt->dt_year = bcdtobin(years_reg) + 2000;
|
||||
dt->dt_wday = bcdtobin(weeks_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
twl_rtc_settime(todr_chip_handle_t tch, struct clock_ymdhms *dt)
|
||||
{
|
||||
struct twl_softc *sc = tch->cookie;
|
||||
|
||||
iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
|
||||
twl_rtc_enable(sc, false);
|
||||
POWER_WRITE(sc, SECONDS_REG, bintobcd(dt->dt_sec));
|
||||
POWER_WRITE(sc, MINUTES_REG, bintobcd(dt->dt_min));
|
||||
POWER_WRITE(sc, HOURS_REG, bintobcd(dt->dt_hour));
|
||||
POWER_WRITE(sc, DAYS_REG, bintobcd(dt->dt_day));
|
||||
POWER_WRITE(sc, MONTHS_REG, bintobcd(dt->dt_mon));
|
||||
POWER_WRITE(sc, YEARS_REG, bintobcd(dt->dt_year % 100));
|
||||
POWER_WRITE(sc, WEEKS_REG, bintobcd(dt->dt_wday));
|
||||
twl_rtc_enable(sc, true);
|
||||
iic_release_bus(sc->sc_i2c, I2C_F_POLL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef FDT
|
||||
static int
|
||||
twl_gpio_config(struct twl_softc *sc, int pin, int flags)
|
||||
{
|
||||
uint8_t dir;
|
||||
|
||||
KASSERT(pin >= 0 && pin < sc->sc_npins);
|
||||
|
||||
dir = INT_READ(sc, GPIODATADIR(pin));
|
||||
|
||||
switch (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
|
||||
case GPIO_PIN_INPUT:
|
||||
dir &= ~PIN_BIT(pin);
|
||||
break;
|
||||
case GPIO_PIN_OUTPUT:
|
||||
dir |= PIN_BIT(pin);
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
INT_WRITE(sc, GPIODATADIR(pin), dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *
|
||||
twl_gpio_acquire(device_t dev, const void *data, size_t len, int flags)
|
||||
{
|
||||
struct twl_softc * const sc = device_private(dev);
|
||||
struct twl_pin *gpin;
|
||||
const u_int *gpio = data;
|
||||
int error;
|
||||
|
||||
if (len != 12)
|
||||
return NULL;
|
||||
|
||||
const uint8_t pin = be32toh(gpio[1]) & 0xff;
|
||||
const bool actlo = (be32toh(gpio[2]) & __BIT(0)) != 0;
|
||||
|
||||
if (pin >= sc->sc_npins)
|
||||
return NULL;
|
||||
|
||||
I2C_LOCK(sc);
|
||||
error = twl_gpio_config(sc, pin, flags);
|
||||
I2C_UNLOCK(sc);
|
||||
|
||||
if (error != 0) {
|
||||
device_printf(dev, "bad pin %d config %#x\n", pin, flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP);
|
||||
gpin->pin_sc = sc;
|
||||
gpin->pin_num = pin;
|
||||
gpin->pin_flags = flags;
|
||||
gpin->pin_actlo = actlo;
|
||||
|
||||
return gpin;
|
||||
}
|
||||
|
||||
static void
|
||||
twl_gpio_release(device_t dev, void *priv)
|
||||
{
|
||||
struct twl_softc * const sc = device_private(dev);
|
||||
struct twl_pin *gpin = priv;
|
||||
|
||||
I2C_LOCK(sc);
|
||||
twl_gpio_config(sc, gpin->pin_num, GPIO_PIN_INPUT);
|
||||
I2C_UNLOCK(sc);
|
||||
|
||||
kmem_free(gpin, sizeof(*gpin));
|
||||
}
|
||||
|
||||
static int
|
||||
twl_gpio_read(device_t dev, void *priv, bool raw)
|
||||
{
|
||||
struct twl_softc * const sc = device_private(dev);
|
||||
struct twl_pin *gpin = priv;
|
||||
uint8_t gpio;
|
||||
int val;
|
||||
|
||||
I2C_LOCK(sc);
|
||||
gpio = INT_READ(sc, GPIODATAIN(gpin->pin_num));
|
||||
I2C_UNLOCK(sc);
|
||||
|
||||
val = __SHIFTOUT(gpio, PIN_BIT(gpin->pin_num));
|
||||
if (!raw && gpin->pin_actlo)
|
||||
val = !val;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void
|
||||
twl_gpio_write(device_t dev, void *priv, int val, bool raw)
|
||||
{
|
||||
struct twl_softc * const sc = device_private(dev);
|
||||
struct twl_pin *gpin = priv;
|
||||
|
||||
if (!raw && gpin->pin_actlo)
|
||||
val = !val;
|
||||
|
||||
I2C_LOCK(sc);
|
||||
if (val)
|
||||
INT_WRITE(sc, SETGPIODATAOUT(gpin->pin_num), PIN_BIT(gpin->pin_num));
|
||||
else
|
||||
INT_WRITE(sc, CLEARGPIODATAOUT(gpin->pin_num), PIN_BIT(gpin->pin_num));
|
||||
I2C_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static struct fdtbus_gpio_controller_func twl_gpio_funcs = {
|
||||
.acquire = twl_gpio_acquire,
|
||||
.release = twl_gpio_release,
|
||||
.read = twl_gpio_read,
|
||||
.write = twl_gpio_write,
|
||||
};
|
||||
#endif /* !FDT */
|
||||
|
||||
static void
|
||||
twl_rtc_attach(struct twl_softc *sc, const int phandle)
|
||||
{
|
||||
iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
|
||||
twl_rtc_enable(sc, true);
|
||||
iic_release_bus(sc->sc_i2c, I2C_F_POLL);
|
||||
|
||||
sc->sc_todr.todr_gettime_ymdhms = twl_rtc_gettime;
|
||||
sc->sc_todr.todr_settime_ymdhms = twl_rtc_settime;
|
||||
sc->sc_todr.cookie = sc;
|
||||
#ifdef FDT
|
||||
fdtbus_todr_attach(sc->sc_dev, phandle, &sc->sc_todr);
|
||||
#else
|
||||
todr_attach(&sc->sc_todr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
twl_gpio_attach(struct twl_softc *sc, const int phandle)
|
||||
{
|
||||
#ifdef FDT
|
||||
fdtbus_register_gpio_controller(sc->sc_dev, phandle, &twl_gpio_funcs);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
twl_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct i2c_attach_args *ia = aux;
|
||||
int match_result;
|
||||
|
||||
if (iic_use_direct_match(ia, match, compat_data, &match_result))
|
||||
return match_result;
|
||||
|
||||
if (ia->ia_addr == 0x48)
|
||||
return I2C_MATCH_ADDRESS_ONLY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
twl_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct twl_softc * const sc = device_private(self);
|
||||
struct i2c_attach_args *ia = aux;
|
||||
uint32_t idcode;
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_i2c = ia->ia_tag;
|
||||
sc->sc_addr = ia->ia_addr;
|
||||
sc->sc_phandle = ia->ia_cookie;
|
||||
sc->sc_npins = TWL_PIN_COUNT;
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": TWL4030");
|
||||
|
||||
#ifdef FDT
|
||||
for (int child = OF_child(sc->sc_phandle); child; child = OF_peer(child)) {
|
||||
if (of_match_compatible(child, gpio_compatible)) {
|
||||
aprint_normal(", GPIO");
|
||||
twl_gpio_attach(sc, child);
|
||||
} else if (of_match_compatible(child, rtc_compatible)) {
|
||||
aprint_normal(", RTC");
|
||||
twl_rtc_attach(sc, child);
|
||||
}
|
||||
}
|
||||
#else
|
||||
aprint_normal("\n");
|
||||
twl_gpio_attach(sc, -1);
|
||||
twl_rtc_attach(sc, -1);
|
||||
#endif
|
||||
|
||||
I2C_LOCK(sc);
|
||||
idcode = INT_READ(sc, IDCODE_7_0);
|
||||
idcode |= (uint32_t)INT_READ(sc, IDCODE_15_8) << 8;
|
||||
idcode |= (uint32_t)INT_READ(sc, IDCODE_23_16) << 16;
|
||||
idcode |= (uint32_t)INT_READ(sc, IDCODE_31_24) << 24;
|
||||
I2C_UNLOCK(sc);
|
||||
|
||||
aprint_normal(", IDCODE 0x%08x\n", idcode);
|
||||
}
|
||||
|
||||
CFATTACH_DECL_NEW(twl, sizeof(struct twl_softc),
|
||||
twl_match, twl_attach, NULL, NULL);
|
Loading…
Reference in New Issue