diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2022-05-19 13:55:43 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2022-05-19 13:55:43 +0200 |
commit | 764fdbaba337e3b58f31ce7b177c4e7c0ba2088d (patch) | |
tree | 954b7c40be6beb5ab6ca9158840e93873cc43427 | |
parent | 28889ccbfe785c59bfaa7c39985c376b697e2331 (diff) | |
parent | 747146a3eb186fb7101f1aaab53d9188dc41bfbb (diff) | |
download | barebox-764fdbaba337e3b58f31ce7b177c4e7c0ba2088d.tar.gz barebox-764fdbaba337e3b58f31ce7b177c4e7c0ba2088d.tar.xz |
Merge branch 'for-next/misc'
40 files changed, 1386 insertions, 190 deletions
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index 75e15cbda4..d303999614 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_MACH_MB7707) += module-mb7707/ obj-$(CONFIG_MACH_MIOA701) += mioa701/ obj-$(CONFIG_MACH_MX23EVK) += freescale-mx23-evk/ obj-$(CONFIG_MACH_MX28EVK) += freescale-mx28-evk/ +obj-$(CONFIG_MACH_MYIRTECH_X335X) += myirtech-x335x/ obj-$(CONFIG_MACH_NESO) += guf-neso/ obj-$(CONFIG_MACH_NETGEAR_RN104) += netgear-rn104/ obj-$(CONFIG_MACH_NETGEAR_RN2120) += netgear-rn2120/ diff --git a/arch/arm/boards/archosg9/board.c b/arch/arm/boards/archosg9/board.c index 3289cfda3d..597830432b 100644 --- a/arch/arm/boards/archosg9/board.c +++ b/arch/arm/boards/archosg9/board.c @@ -5,10 +5,10 @@ #include <init.h> #include <asm/armlinux.h> #include <generated/mach-types.h> +#include <mach/devices.h> #include <mach/omap4-silicon.h> #include <mach/omap4-devices.h> #include <mach/omap4_rom_usb.h> -#include <mach/omap-fb.h> #include <linux/sizes.h> #include <i2c/i2c.h> #include <gpio.h> diff --git a/arch/arm/boards/myirtech-x335x/Makefile b/arch/arm/boards/myirtech-x335x/Makefile new file mode 100644 index 0000000000..05d9fc7bc3 --- /dev/null +++ b/arch/arm/boards/myirtech-x335x/Makefile @@ -0,0 +1,3 @@ +lwl-y += lowlevel.o +obj-y += board.o +bbenv-$(CONFIG_DEFAULT_ENVIRONMENT) += defaultenv-myirtech-x335x diff --git a/arch/arm/boards/myirtech-x335x/board.c b/arch/arm/boards/myirtech-x335x/board.c new file mode 100644 index 0000000000..c6d808284e --- /dev/null +++ b/arch/arm/boards/myirtech-x335x/board.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-FileCopyrightText: Alexander Shiyan <shc_work@mail.ru> */ + +#include <bootsource.h> +#include <common.h> +#include <driver.h> +#include <envfs.h> +#include <init.h> +#include <linux/sizes.h> +#include <mach/am33xx-generic.h> + +static struct omap_barebox_part myir_barebox_part = { + .nand_offset = SZ_128K * 4, + .nand_size = SZ_1M, +}; + +static __init int myir_devices_init(void) +{ + if (!of_machine_is_compatible("myir,myc-am335x")) + return 0; + + am33xx_register_ethaddr(0, 0); + am33xx_register_ethaddr(1, 1); + + switch (bootsource_get()) { + case BOOTSOURCE_MMC: + omap_set_bootmmc_devname("mmc0"); + break; + case BOOTSOURCE_NAND: + omap_set_barebox_part(&myir_barebox_part); + break; + default: + break; + } + + if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT)) + defaultenv_append_directory(defaultenv_myirtech_x335x); + + if (IS_ENABLED(CONFIG_SHELL_NONE)) + return am33xx_of_register_bootdevice(); + + return 0; +} +coredevice_initcall(myir_devices_init); diff --git a/arch/arm/boards/myirtech-x335x/defaultenv-myirtech-x335x/boot/nand b/arch/arm/boards/myirtech-x335x/defaultenv-myirtech-x335x/boot/nand new file mode 100644 index 0000000000..c000041095 --- /dev/null +++ b/arch/arm/boards/myirtech-x335x/defaultenv-myirtech-x335x/boot/nand @@ -0,0 +1,4 @@ +#!/bin/sh + +global.bootm.image="/dev/nand0.system.ubi.kernel" +global.linux.bootargs.dyn.root="ubi.mtd=system ubi.block=0,root root=fe00 ro" diff --git a/arch/arm/boards/myirtech-x335x/defaultenv-myirtech-x335x/nv/boot.default b/arch/arm/boards/myirtech-x335x/defaultenv-myirtech-x335x/nv/boot.default new file mode 100644 index 0000000000..026a25cc7e --- /dev/null +++ b/arch/arm/boards/myirtech-x335x/defaultenv-myirtech-x335x/nv/boot.default @@ -0,0 +1 @@ +nand diff --git a/arch/arm/boards/myirtech-x335x/lowlevel.c b/arch/arm/boards/myirtech-x335x/lowlevel.c new file mode 100644 index 0000000000..e867a0be7d --- /dev/null +++ b/arch/arm/boards/myirtech-x335x/lowlevel.c @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-FileCopyrightText: Alexander Shiyan <shc_work@mail.ru> */ + +#include <io.h> +#include <asm/barebox-arm-head.h> +#include <asm/barebox-arm.h> +#include <debug_ll.h> +#include <init.h> +#include <linux/sizes.h> +#include <mach/am33xx-clock.h> +#include <mach/am33xx-generic.h> +#include <mach/am33xx-mux.h> +#include <mach/generic.h> +#include <mach/sdrc.h> +#include <mach/sys_info.h> +#include <mach/wdt.h> + +#define AM335X_ZCZ_1000 0x1c2f + +static const struct am33xx_ddr_data ddr3_data = { + .rd_slave_ratio0 = 0x38, + .wr_dqs_slave_ratio0 = 0x44, + .fifo_we_slave_ratio0 = 0x94, + .wr_slave_ratio0 = 0x7d, + .use_rank0_delay = 0x01, + .dll_lock_diff0 = 0x00, +}; + +static const struct am33xx_cmd_control ddr3_cmd_ctrl = { + .slave_ratio0 = 0x80, + .dll_lock_diff0 = 0x01, + .invert_clkout0 = 0x00, + .slave_ratio1 = 0x80, + .dll_lock_diff1 = 0x01, + .invert_clkout1 = 0x00, + .slave_ratio2 = 0x80, + .dll_lock_diff2 = 0x01, + .invert_clkout2 = 0x00, +}; + +/* CPU module contains 512MB (2*256MB) DDR3 SDRAM (2*128MB compatible), + * so we configure EMIF for 512MB then detect real size of memory. + */ +static const struct am33xx_emif_regs ddr3_regs = { + .emif_read_latency = 0x00100007, + .emif_tim1 = 0x0aaad4db, + .emif_tim2 = 0x266b7fda, + .emif_tim3 = 0x501f867f, + .zq_config = 0x50074be4, + .sdram_config = 0x61c05332, + .sdram_config2 = 0x00, + .sdram_ref_ctrl = 0xc30, +}; + +extern char __dtb_z_am335x_myirtech_myd_start[]; + +ENTRY_FUNCTION(start_am33xx_myirtech_sram, bootinfo, r1, r2) +{ + int mpupll; + void *fdt; + + am33xx_save_bootinfo((void *)bootinfo); + + arm_cpu_lowlevel_init(); + + relocate_to_current_adr(); + setup_c(); + + fdt = __dtb_z_am335x_myirtech_myd_start; + + /* WDT1 is already running when the bootloader gets control + * Disable it to avoid "random" resets + */ + __raw_writel(WDT_DISABLE_CODE1, AM33XX_WDT_REG(WSPR)); + while (__raw_readl(AM33XX_WDT_REG(WWPS)) != 0x0); + __raw_writel(WDT_DISABLE_CODE2, AM33XX_WDT_REG(WSPR)); + while (__raw_readl(AM33XX_WDT_REG(WWPS)) != 0x0); + + mpupll = MPUPLL_M_800; + if (am33xx_get_cpu_rev() == AM335X_ES2_1) { + u32 deviceid = readl(AM33XX_EFUSE_SMA) & 0x1fff; + if (deviceid == AM335X_ZCZ_1000) + mpupll = MPUPLL_M_1000; + } + + am33xx_pll_init(mpupll, DDRPLL_M_400); + + am335x_sdram_init(0x18b, &ddr3_cmd_ctrl, &ddr3_regs, &ddr3_data); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) { + am33xx_uart_soft_reset(IOMEM(AM33XX_UART0_BASE)); + am33xx_enable_uart0_pin_mux(); + omap_uart_lowlevel_init(IOMEM(AM33XX_UART0_BASE)); + putc_ll('>'); + } + + barebox_arm_entry(AM33XX_DRAM_ADDR_SPACE_START, SZ_256M, fdt); +} + +ENTRY_FUNCTION(start_am33xx_myirtech_sdram, r0, r1, r2) +{ + void *fdt; + u32 sdram_size; + + fdt = __dtb_z_am335x_myirtech_myd_start; + + fdt += get_runtime_offset(); + + /* Detect 256M/512M module variant */ + __raw_writel(SZ_512M, AM33XX_DRAM_ADDR_SPACE_START + SZ_256M); + __raw_writel(SZ_256M, AM33XX_DRAM_ADDR_SPACE_START + 0); + sdram_size = __raw_readl(AM33XX_DRAM_ADDR_SPACE_START + SZ_256M); + + barebox_arm_entry(AM33XX_DRAM_ADDR_SPACE_START, sdram_size, fdt); +} diff --git a/arch/arm/boards/phytec-phycore-omap4460/board.c b/arch/arm/boards/phytec-phycore-omap4460/board.c index 9e8b9e56a7..e25ff5eb31 100644 --- a/arch/arm/boards/phytec-phycore-omap4460/board.c +++ b/arch/arm/boards/phytec-phycore-omap4460/board.c @@ -10,10 +10,10 @@ #include <envfs.h> #include <asm/armlinux.h> #include <generated/mach-types.h> +#include <mach/devices.h> #include <mach/omap4-silicon.h> #include <mach/omap4-devices.h> #include <mach/omap4-clock.h> -#include <mach/omap-fb.h> #include <mach/sdrc.h> #include <mach/sys_info.h> #include <mach/syslib.h> @@ -292,8 +292,7 @@ static int pcm049_devices_init(void) armlinux_set_architecture(MACH_TYPE_PCM049); - if (IS_ENABLED(CONFIG_DRIVER_VIDEO_OMAP)) - omap_add_display(&pcm049_fb_data); + omap_add_display(&pcm049_fb_data); if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT_GENERIC)) defaultenv_append_directory(defaultenv_phytec_phycore_omap4460); diff --git a/arch/arm/configs/am335x_mlo_defconfig b/arch/arm/configs/am335x_mlo_defconfig index 51d238db3e..83bb20e4b5 100644 --- a/arch/arm/configs/am335x_mlo_defconfig +++ b/arch/arm/configs/am335x_mlo_defconfig @@ -5,6 +5,7 @@ CONFIG_OMAP_SERIALBOOT=y CONFIG_OMAP_MULTI_BOARDS=y CONFIG_MACH_AFI_GF=y CONFIG_MACH_BEAGLEBONE=y +CONFIG_MACH_MYIRTECH_X335X=y CONFIG_MACH_PHYTEC_SOM_AM335X=y CONFIG_THUMB2_BAREBOX=y # CONFIG_MEMINFO is not set diff --git a/arch/arm/configs/omap_defconfig b/arch/arm/configs/omap_defconfig index 59892cb231..ae4d1a67da 100644 --- a/arch/arm/configs/omap_defconfig +++ b/arch/arm/configs/omap_defconfig @@ -6,6 +6,7 @@ CONFIG_OMAP_MULTI_BOARDS=y CONFIG_MACH_AFI_GF=y CONFIG_MACH_BEAGLE=y CONFIG_MACH_BEAGLEBONE=y +CONFIG_MACH_MYIRTECH_X335X=y CONFIG_MACH_PHYTEC_SOM_AM335X=y CONFIG_MACH_VSCOM_BALTOS=y CONFIG_MACH_WAGO_PFC_AM35XX=y @@ -46,6 +47,7 @@ CONFIG_CMD_GO=y CONFIG_CMD_LOADB=y CONFIG_CMD_RESET=y CONFIG_CMD_UIMAGE=y +CONFIG_CMD_BOOTCHOOSER=y CONFIG_CMD_PARTITION=y CONFIG_CMD_UBIFORMAT=y CONFIG_CMD_EXPORT=y @@ -93,7 +95,6 @@ CONFIG_CMD_OF_FIXUP_STATUS=y CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y CONFIG_CMD_STATE=y -CONFIG_CMD_BOOTCHOOSER=y CONFIG_NET=y CONFIG_NET_NFS=y CONFIG_NET_NETCONSOLE=y diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index e0177d84e4..46e5e67672 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -40,6 +40,7 @@ lwl-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += armada-xp-gp-bb.dtb.o lwl-$(CONFIG_MACH_MARVELL_ARMADA_XP_DB) += armada-xp-db-bb.dtb.o lwl-$(CONFIG_MACH_MB7707) += module-mb7707.dtb.o lwl-$(CONFIG_MACH_MX28EVK) += imx28-evk.dtb.o +lwl-$(CONFIG_MACH_MYIRTECH_X335X) += am335x-myirtech-myd.dtb.o lwl-$(CONFIG_MACH_NETGEAR_RN104) += armada-370-rn104-bb.dtb.o lwl-$(CONFIG_MACH_NETGEAR_RN2120) += armada-xp-rn2120-bb.dtb.o lwl-$(CONFIG_MACH_NITROGEN6) += imx6q-nitrogen6x.dtb.o imx6dl-nitrogen6x.dtb.o imx6qp-nitrogen6_max.dtb.o diff --git a/arch/arm/dts/am335x-myirtech-myd.dts b/arch/arm/dts/am335x-myirtech-myd.dts new file mode 100644 index 0000000000..6ec65e533d --- /dev/null +++ b/arch/arm/dts/am335x-myirtech-myd.dts @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* SPDX-FileCopyrightText: Alexander Shiyan, <shc_work@mail.ru> */ + +/dts-v1/; + +#include <arm/am335x-myirtech-myd.dts> + +/ { + chosen { + environment { + compatible = "barebox,environment"; + device-path = &nand_environment; + }; + }; + +}; + +&nand0 { + /delete-node/ partition@0; + /delete-node/ partition@20000; + + nand_parts: partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "MLO"; + reg = <0x00000 0x20000>; + }; + + partition@80000 { + label = "boot"; + reg = <0x80000 0x100000>; + }; + + nand_environment: partition@180000 { + label = "env"; + reg = <0x180000 0x40000>; + }; + + partition@1c0000 { + label = "system"; + reg = <0x1c0000 0>; + }; + }; +}; diff --git a/arch/arm/dts/rk3568-bpi-r2-pro.dts b/arch/arm/dts/rk3568-bpi-r2-pro.dts index db13f00cd0..da76ab64c1 100644 --- a/arch/arm/dts/rk3568-bpi-r2-pro.dts +++ b/arch/arm/dts/rk3568-bpi-r2-pro.dts @@ -560,16 +560,13 @@ status = "okay"; }; -&usbdrd_dwc3 { +&usb_host0_xhci { dr_mode = "host"; extcon = <&usb2phy0>; -}; - -&usbdrd30 { status = "okay"; }; -&usbhost30 { +&usb_host1_xhci { status = "okay"; }; diff --git a/arch/arm/dts/rk3568-evb1-v10.dts b/arch/arm/dts/rk3568-evb1-v10.dts index 4ded9b1735..df5633978d 100644 --- a/arch/arm/dts/rk3568-evb1-v10.dts +++ b/arch/arm/dts/rk3568-evb1-v10.dts @@ -547,24 +547,20 @@ status = "okay"; }; -&usb_host1_ehci { +&usb_host0_xhci { + extcon = <&usb2phy0>; status = "okay"; }; -&usb_host1_ohci { +&usb_host1_ehci { status = "okay"; }; -&usbdrd_dwc3 { - dr_mode = "otg"; - extcon = <&usb2phy0>; -}; - -&usbdrd30 { +&usb_host1_ohci { status = "okay"; }; -&usbhost30 { +&usb_host1_xhci { status = "okay"; }; diff --git a/arch/arm/dts/rk3568.dtsi b/arch/arm/dts/rk3568.dtsi index 0f19d3f0c0..3c458754af 100644 --- a/arch/arm/dts/rk3568.dtsi +++ b/arch/arm/dts/rk3568.dtsi @@ -198,62 +198,38 @@ }; }; - usbdrd30: usbdrd { - compatible = "rockchip,rk3568-dwc3", "rockchip,rk3399-dwc3"; + usb_host0_xhci: usb@fcc00000 { + compatible = "rockchip,rk3568-dwc3", "snps,dwc3"; + reg = <0x0 0xfcc00000 0x0 0x400000>; + interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru CLK_USB3OTG0_REF>, <&cru CLK_USB3OTG0_SUSPEND>, - <&cru ACLK_USB3OTG0>, <&cru PCLK_PIPE>; + <&cru ACLK_USB3OTG0>; clock-names = "ref_clk", "suspend_clk", - "bus_clk", "pipe_clk"; - #address-cells = <2>; - #size-cells = <2>; - ranges; + "bus_clk"; + dr_mode = "otg"; + phys = <&u2phy0_otg>, <&combphy0_us PHY_TYPE_USB3>; + phy-names = "usb2-phy", "usb3-phy"; + phy_type = "utmi_wide"; + resets = <&cru SRST_USB3OTG0>; + snps,dis_u2_susphy_quirk; status = "disabled"; - - usbdrd_dwc3: dwc3@fcc00000 { - compatible = "snps,dwc3"; - reg = <0x0 0xfcc00000 0x0 0x400000>; - interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; - dr_mode = "otg"; - phys = <&u2phy0_otg>, <&combphy0_us PHY_TYPE_USB3>; - phy-names = "usb2-phy", "usb3-phy"; - phy_type = "utmi_wide"; - resets = <&cru SRST_USB3OTG0>; - reset-names = "usb3-otg"; - snps,dis_enblslpm_quirk; - snps,dis-u2-freeclk-exists-quirk; - snps,dis-del-phy-power-chg-quirk; - snps,dis-tx-ipgap-linecheck-quirk; - snps,xhci-trb-ent-quirk; - }; }; - usbhost30: usbhost { - compatible = "rockchip,rk3568-dwc3", "rockchip,rk3399-dwc3"; + usb_host1_xhci: usb@fd000000 { + compatible = "rockchip,rk3568-dwc3", "snps,dwc3"; + reg = <0x0 0xfd000000 0x0 0x400000>; + interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru CLK_USB3OTG1_REF>, <&cru CLK_USB3OTG1_SUSPEND>, - <&cru ACLK_USB3OTG1>, <&cru PCLK_PIPE>; + <&cru ACLK_USB3OTG1>; clock-names = "ref_clk", "suspend_clk", - "bus_clk", "pipe_clk"; - #address-cells = <2>; - #size-cells = <2>; - ranges; + "bus_clk"; + dr_mode = "host"; + phys = <&u2phy0_host>, <&combphy1_usq PHY_TYPE_USB3>; + phy-names = "usb2-phy", "usb3-phy"; + phy_type = "utmi_wide"; + resets = <&cru SRST_USB3OTG1>; + snps,dis_u2_susphy_quirk; status = "disabled"; - - usbhost_dwc3: dwc3@fd000000 { - compatible = "snps,dwc3"; - reg = <0x0 0xfd000000 0x0 0x400000>; - interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>; - dr_mode = "host"; - phys = <&u2phy0_host>, <&combphy1_usq PHY_TYPE_USB3>; - phy-names = "usb2-phy", "usb3-phy"; - phy_type = "utmi_wide"; - resets = <&cru SRST_USB3OTG1>; - reset-names = "usb3-host"; - snps,dis_enblslpm_quirk; - snps,dis-u2-freeclk-exists-quirk; - snps,dis-del-phy-power-chg-quirk; - snps,dis-tx-ipgap-linecheck-quirk; - snps,xhci-trb-ent-quirk; - }; }; gic: interrupt-controller@fd400000 { @@ -367,11 +343,10 @@ #phy-cells = <1>; clocks = <&pmucru CLK_PCIEPHY0_REF>, <&cru PCLK_PIPEPHY0>, <&cru PCLK_PIPE>; - clock-names = "refclk", "apbclk", "pipe_clk"; + clock-names = "ref", "apb", "pipe"; assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>; assigned-clock-rates = <24000000>; - resets = <&cru SRST_P_PIPEPHY0>, <&cru SRST_PIPEPHY0>; - reset-names = "combphy-apb", "combphy"; + resets = <&cru SRST_PIPEPHY0>; rockchip,pipe-grf = <&pipegrf>; rockchip,pipe-phy-grf = <&pipe_phy_grf0>; status = "disabled"; @@ -383,11 +358,10 @@ #phy-cells = <1>; clocks = <&pmucru CLK_PCIEPHY1_REF>, <&cru PCLK_PIPEPHY1>, <&cru PCLK_PIPE>; - clock-names = "refclk", "apbclk", "pipe_clk"; + clock-names = "ref", "apb", "pipe"; assigned-clocks = <&pmucru CLK_PCIEPHY1_REF>; assigned-clock-rates = <24000000>; - resets = <&cru SRST_P_PIPEPHY1>, <&cru SRST_PIPEPHY1>; - reset-names = "combphy-apb", "combphy"; + resets = <&cru SRST_PIPEPHY1>; rockchip,pipe-grf = <&pipegrf>; rockchip,pipe-phy-grf = <&pipe_phy_grf1>; status = "disabled"; diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig index 220b635167..f0e035e31e 100644 --- a/arch/arm/mach-omap/Kconfig +++ b/arch/arm/mach-omap/Kconfig @@ -168,6 +168,12 @@ config MACH_BEAGLEBONE help Say Y here if you are using Beagle Bone +config MACH_MYIRTECH_X335X + bool "MYIR Tech Limited SOMs" + select ARCH_AM33XX + help + Say Y here if you are using a TI AM335X based MYIR SOM + config MACH_PHYTEC_SOM_AM335X bool "Phytec AM335X SOMs" select ARCH_AM33XX diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile index 36b2aa090e..e81284ec3b 100644 --- a/arch/arm/mach-omap/Makefile +++ b/arch/arm/mach-omap/Makefile @@ -15,7 +15,7 @@ # GNU General Public License for more details. # # -obj-$(CONFIG_ARCH_OMAP) += syslib.o omap_devices.o omap_generic.o omap_fb.o +obj-$(CONFIG_ARCH_OMAP) += syslib.o omap_devices.o omap_generic.o pbl-$(CONFIG_ARCH_OMAP) += syslib.o obj-$(CONFIG_ARCH_OMAP3) += omap3_generic.o auxcr.o pbl-$(CONFIG_ARCH_OMAP3) += omap3_generic.o auxcr.o diff --git a/arch/arm/mach-omap/include/mach/am33xx-clock.h b/arch/arm/mach-omap/include/mach/am33xx-clock.h index 3c2143d600..b0293db990 100644 --- a/arch/arm/mach-omap/include/mach/am33xx-clock.h +++ b/arch/arm/mach-omap/include/mach/am33xx-clock.h @@ -25,6 +25,7 @@ #define MPUPLL_M_600 600 /* 125 * n */ #define MPUPLL_M_720 720 /* 125 * n */ #define MPUPLL_M_800 800 +#define MPUPLL_M_1000 1000 #define MPUPLL_M2 1 diff --git a/arch/arm/mach-omap/include/mach/am33xx-silicon.h b/arch/arm/mach-omap/include/mach/am33xx-silicon.h index 0729369255..0467dac03b 100644 --- a/arch/arm/mach-omap/include/mach/am33xx-silicon.h +++ b/arch/arm/mach-omap/include/mach/am33xx-silicon.h @@ -201,6 +201,8 @@ #define AM33XX_MAC_ID1_HI (AM33XX_CTRL_BASE + 0x63c) #define AM33XX_MAC_MII_SEL (AM33XX_CTRL_BASE + 0x650) +#define AM33XX_EFUSE_SMA (AM33XX_CTRL_BASE + 0x7fc) + struct am33xx_cmd_control { u32 slave_ratio0; u32 dll_lock_diff0; diff --git a/arch/arm/mach-omap/include/mach/devices.h b/arch/arm/mach-omap/include/mach/devices.h index 0f9fdf1ca5..06fd2a8dd3 100644 --- a/arch/arm/mach-omap/include/mach/devices.h +++ b/arch/arm/mach-omap/include/mach/devices.h @@ -4,6 +4,7 @@ #define __MACH_OMAP_DEVICES_H #include <mach/omap_hsmmc.h> +#include <video/omap-fb.h> void omap_add_ram0(resource_size_t size); @@ -11,4 +12,6 @@ void omap_add_sram0(resource_size_t base, resource_size_t size); struct device_d *omap_add_uart(int id, unsigned long base); +struct device_d *omap_add_display(struct omapfb_platform_data *o_pdata); + #endif /* __MACH_OMAP_DEVICES_H */ diff --git a/arch/arm/mach-omap/omap4_generic.c b/arch/arm/mach-omap/omap4_generic.c index c9a89c57b7..406b686318 100644 --- a/arch/arm/mach-omap/omap4_generic.c +++ b/arch/arm/mach-omap/omap4_generic.c @@ -433,38 +433,29 @@ unsigned int omap4_revision(void) return OMAP4430_ES1_0; case MIDR_CORTEX_A9_R1P2: switch (readl(CONTROL_ID_CODE)) { - case OMAP4_CONTROL_ID_CODE_ES2_0: - return OMAP4430_ES2_0; - break; case OMAP4_CONTROL_ID_CODE_ES2_1: return OMAP4430_ES2_1; - break; case OMAP4_CONTROL_ID_CODE_ES2_2: return OMAP4430_ES2_2; - break; default: - return OMAP4430_ES2_0; break; } - break; + return OMAP4430_ES2_0; case MIDR_CORTEX_A9_R1P3: return OMAP4430_ES2_3; - break; case MIDR_CORTEX_A9_R2P10: switch (readl(CONTROL_ID_CODE)) { case OMAP4460_CONTROL_ID_CODE_ES1_1: return OMAP4460_ES1_1; - break; - case OMAP4460_CONTROL_ID_CODE_ES1_0: default: - return OMAP4460_ES1_0; break; } - break; + return OMAP4460_ES1_0; default: - return OMAP4430_SILICON_ID_INVALID; break; } + + return OMAP4430_SILICON_ID_INVALID; } /* diff --git a/arch/arm/mach-omap/omap_devices.c b/arch/arm/mach-omap/omap_devices.c index 7c36b8819d..beae59f74d 100644 --- a/arch/arm/mach-omap/omap_devices.c +++ b/arch/arm/mach-omap/omap_devices.c @@ -26,3 +26,32 @@ struct device_d *omap_add_uart(int id, unsigned long base) return add_generic_device("omap-uart", id, NULL, base, 1024, IORESOURCE_MEM | IORESOURCE_MEM_8BIT, &serial_plat); } + +#if defined(CONFIG_DRIVER_VIDEO_OMAP) +static struct resource omapfb_resources[] = { + { + .name = "omap4_dss", + .start = 0x48040000, + .end = 0x48040000 + 512 - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, + }, { + .name = "omap4_dispc", + .start = 0x48041000, + .end = 0x48041000 + 3072 - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, + }, +}; + +struct device_d *omap_add_display(struct omapfb_platform_data *o_pdata) +{ + return add_generic_device_res("omap_fb", -1, + omapfb_resources, + ARRAY_SIZE(omapfb_resources), + o_pdata); +} +#else +struct device_d *omap_add_display(struct omapfb_platform_data *o_pdata) +{ + return NULL; +} +#endif diff --git a/arch/arm/mach-omap/omap_fb.c b/arch/arm/mach-omap/omap_fb.c deleted file mode 100644 index 0bd51c5f55..0000000000 --- a/arch/arm/mach-omap/omap_fb.c +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include <driver.h> -#include <common.h> -#include <linux/ioport.h> -#include <mach/omap-fb.h> - -#if defined(CONFIG_DRIVER_VIDEO_OMAP) -static struct resource omapfb_resources[] = { - { - .name = "omap4_dss", - .start = 0x48040000, - .end = 0x48040000 + 512 - 1, - .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, - }, { - .name = "omap4_dispc", - .start = 0x48041000, - .end = 0x48041000 + 3072 - 1, - .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, - }, -}; - -struct device_d *omap_add_display(struct omapfb_platform_data *o_pdata) -{ - return add_generic_device_res("omap_fb", -1, - omapfb_resources, - ARRAY_SIZE(omapfb_resources), - o_pdata); -} -#else -struct device_d *omap_add_display(struct omapfb_platform_data *o_pdata) -{ - return NULL; -} -#endif -EXPORT_SYMBOL(omap_add_display); diff --git a/arch/riscv/configs/sifive_defconfig b/arch/riscv/configs/sifive_defconfig index 59cfebf194..6ebe6eaf37 100644 --- a/arch/riscv/configs/sifive_defconfig +++ b/arch/riscv/configs/sifive_defconfig @@ -13,13 +13,10 @@ CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y -CONFIG_IMD_TARGET=y CONFIG_CONSOLE_ALLOW_COLOR=y CONFIG_PBL_CONSOLE=y CONFIG_PARTITION_DISK_EFI=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y -CONFIG_BAREBOXENV_TARGET=y -CONFIG_BAREBOXCRC32_TARGET=y CONFIG_STATE=y CONFIG_STATE_CRYPTO=y CONFIG_BOOTCHOOSER=y @@ -85,20 +82,21 @@ CONFIG_VIRTIO_CONSOLE=y CONFIG_SERIAL_SIFIVE=y CONFIG_DRIVER_NET_MACB=y CONFIG_DRIVER_SPI_GPIO=y +CONFIG_SPI_SIFIVE=y CONFIG_I2C=y CONFIG_I2C_GPIO=y CONFIG_MTD=y -# CONFIG_MTD_OOB_DEVICE is not set +CONFIG_MTD_RAW_DEVICE=y CONFIG_MTD_CONCAT=y CONFIG_MTD_M25P80=y CONFIG_DRIVER_CFI=y CONFIG_DRIVER_CFI_BANK_WIDTH_8=y -CONFIG_DISK=y -CONFIG_DISK_WRITE=y CONFIG_VIRTIO_BLK=y CONFIG_VIDEO=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_DRIVER_VIDEO_SIMPLEFB_CLIENT=y +CONFIG_MCI=y +CONFIG_MCI_SPI=y CONFIG_CLOCKSOURCE_DUMMY_RATE=60000 CONFIG_EEPROM_AT24=y CONFIG_HWRNG=y @@ -126,3 +124,6 @@ CONFIG_ZSTD_DECOMPRESS=y CONFIG_XZ_DECOMPRESS=y CONFIG_BASE64=y CONFIG_DIGEST_CRC32_GENERIC=y +CONFIG_IMD_TARGET=y +CONFIG_BAREBOXENV_TARGET=y +CONFIG_BAREBOXCRC32_TARGET=y diff --git a/drivers/ata/disk_ata_drive.c b/drivers/ata/disk_ata_drive.c index f36e06328c..7df0879b19 100644 --- a/drivers/ata/disk_ata_drive.c +++ b/drivers/ata/disk_ata_drive.c @@ -80,9 +80,9 @@ static void __maybe_unused ata_dump_id(uint16_t *id) ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); printf("Product model number: %s\n\r", product); - /* Total sectors of device */ + /* Total sectors of device */ n_sectors = ata_id_n_sectors(id); - printf("Capablity: %lld sectors\n\r", n_sectors); + printf("Capacity: %lld sectors\n\r", n_sectors); printf ("id[49]: capabilities = 0x%04x\n" "id[53]: field valid = 0x%04x\n" @@ -95,12 +95,14 @@ static void __maybe_unused ata_dump_id(uint16_t *id) id[ATA_ID_PIO_MODES], id[ATA_ID_QUEUE_DEPTH]); - printf ("id[76]: sata capablity = 0x%04x\n" + printf ("id[76]: sata capabilities 1 = 0x%04x\n" + "id[77]: sata capabilities 2 = 0x%04x\n" "id[78]: sata features supported = 0x%04x\n" - "id[79]: sata features enable = 0x%04x\n", - id[76], /* FIXME */ - id[78], /* FIXME */ - id[79]); /* FIXME */ + "id[79]: sata features enabled = 0x%04x\n", + id[ATA_ID_SATA_CAPAB_1], + id[ATA_ID_SATA_CAPAB_2], + id[ATA_ID_SATA_FEAT_SUPP], + id[ATA_ID_SATA_FEAT_ENABLE]); printf ("id[80]: major version = 0x%04x\n" "id[81]: minor version = 0x%04x\n" @@ -108,12 +110,13 @@ static void __maybe_unused ata_dump_id(uint16_t *id) "id[83]: command set supported 2 = 0x%04x\n" "id[84]: command set extension = 0x%04x\n", id[ATA_ID_MAJOR_VER], - id[81], /* FIXME */ + id[ATA_ID_MINOR_VER], id[ATA_ID_COMMAND_SET_1], id[ATA_ID_COMMAND_SET_2], id[ATA_ID_CFSSE]); - printf ("id[85]: command set enable 1 = 0x%04x\n" - "id[86]: command set enable 2 = 0x%04x\n" + + printf ("id[85]: command set enabled 1 = 0x%04x\n" + "id[86]: command set enabled 2 = 0x%04x\n" "id[87]: command set default = 0x%04x\n" "id[88]: udma = 0x%04x\n" "id[93]: hardware reset result = 0x%04x\n", diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index d4e74552b7..58f8656067 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -70,4 +70,12 @@ config I2C_RK3X Say Y here to include support for the I2C adapter in Rockchip RK3xxx SoCs. +config I2C_CADENCE + bool "Cadence I2C adapter" + depends on HAVE_CLK + depends on ARCH_ZYNQMP || COMPILE_TEST + help + Say Y here to include support for the Cadence I2C host controller found + in Zynq UltraScale+ MPSoCs. + endmenu diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index d6273f3d86..a8661f605e 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o obj-$(CONFIG_I2C_DESIGNWARE) += i2c-designware.o obj-$(CONFIG_I2C_STM32) += i2c-stm32.o obj-$(CONFIG_I2C_RK3X) += i2c-rockchip.o +obj-$(CONFIG_I2C_CADENCE) += i2c-cadence.o diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c new file mode 100644 index 0000000000..5537efff23 --- /dev/null +++ b/drivers/i2c/busses/i2c-cadence.c @@ -0,0 +1,453 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * I2C bus driver for the Cadence I2C host controller (master only). + * + * Partly based on the driver in the Linux kernel + * Copyright (C) 2009 - 2014 Xilinx, Inc. + * + * Copyright (C) 2022 Matthias Fend <matthias.fend@emfend.at> + */ + +#include <common.h> +#include <i2c/i2c.h> +#include <linux/iopoll.h> +#include <errno.h> +#include <linux/err.h> +#include <driver.h> +#include <io.h> +#include <linux/clk.h> +#include <regmap.h> + +struct __packed i2c_regs { + u32 control; + u32 status; + u32 address; + u32 data; + u32 interrupt_status; + u32 transfer_size; + u32 slave_mon_pause; + u32 time_out; + u32 interrupt_mask; + u32 interrupt_enable; + u32 interrupt_disable; + u32 glitch_filter; +}; + +/* Control register fields */ +#define CDNS_I2C_CONTROL_RW BIT(0) +#define CDNS_I2C_CONTROL_MS BIT(1) +#define CDNS_I2C_CONTROL_NEA BIT(2) +#define CDNS_I2C_CONTROL_ACKEN BIT(3) +#define CDNS_I2C_CONTROL_HOLD BIT(4) +#define CDNS_I2C_CONTROL_SLVMON BIT(5) +#define CDNS_I2C_CONTROL_CLR_FIFO BIT(6) +#define CDNS_I2C_CONTROL_DIV_B_SHIFT 8 +#define CDNS_I2C_CONTROL_DIV_B_MASK (0x3F << CDNS_I2C_CONTROL_DIV_B_SHIFT) +#define CDNS_I2C_CONTROL_DIV_A_SHIFT 14 +#define CDNS_I2C_CONTROL_DIV_A_MASK (0x03 << CDNS_I2C_CONTROL_DIV_A_SHIFT) + +#define CDNS_I2C_CONTROL_DIV_B_MAX 64 +#define CDNS_I2C_CONTROL_DIV_A_MAX 4 + +/* Status register fields */ +#define CDNS_I2C_STATUS_RXRW BIT(3) +#define CDNS_I2C_STATUS_RXDV BIT(5) +#define CDNS_I2C_STATUS_TXDV BIT(6) +#define CDNS_I2C_STATUS_RXOVF BIT(7) +#define CDNS_I2C_STATUS_BA BIT(8) + +/* Address register fields */ +#define CDNS_I2C_ADDRESS_MASK 0x3FF + +/* Interrupt register fields */ +#define CDNS_I2C_INTERRUPT_COMP BIT(0) +#define CDNS_I2C_INTERRUPT_DATA BIT(1) +#define CDNS_I2C_INTERRUPT_NACK BIT(2) +#define CDNS_I2C_INTERRUPT_TO BIT(3) +#define CDNS_I2C_INTERRUPT_SLVRDY BIT(4) +#define CDNS_I2C_INTERRUPT_RXOVF BIT(5) +#define CDNS_I2C_INTERRUPT_TXOVF BIT(6) +#define CDNS_I2C_INTERRUPT_RXUNF BIT(7) +#define CDNS_I2C_INTERRUPT_ARBLOST BIT(9) + +#define CDNS_I2C_INTERRUPTS_MASK_MASTER (CDNS_I2C_INTERRUPT_COMP | \ + CDNS_I2C_INTERRUPT_DATA | \ + CDNS_I2C_INTERRUPT_NACK | \ + CDNS_I2C_INTERRUPT_RXOVF | \ + CDNS_I2C_INTERRUPT_TXOVF | \ + CDNS_I2C_INTERRUPT_RXUNF | \ + CDNS_I2C_INTERRUPT_ARBLOST) + +#define CDNS_I2C_INTERRUPTS_MASK_ALL (CDNS_I2C_INTERRUPT_COMP | \ + CDNS_I2C_INTERRUPT_DATA | \ + CDNS_I2C_INTERRUPT_NACK | \ + CDNS_I2C_INTERRUPT_TO | \ + CDNS_I2C_INTERRUPT_SLVRDY | \ + CDNS_I2C_INTERRUPT_RXOVF | \ + CDNS_I2C_INTERRUPT_TXOVF | \ + CDNS_I2C_INTERRUPT_RXUNF | \ + CDNS_I2C_INTERRUPT_ARBLOST) + +#define CDNS_I2C_FIFO_DEPTH 16 +#define CDNS_I2C_TRANSFER_SIZE_MAX 255 +#define CDNS_I2C_TRANSFER_SIZE (CDNS_I2C_TRANSFER_SIZE_MAX - 3) + +#define I2C_TIMEOUT_US (100 * USEC_PER_MSEC) + +struct cdns_i2c { + struct i2c_adapter adapter; + struct clk *clk; + struct i2c_regs *regs; + bool bus_hold_flag; +}; + +static void cdns_i2c_reset_hardware(struct cdns_i2c *i2c) +{ + struct i2c_regs *regs = i2c->regs; + u32 regval; + + writel(CDNS_I2C_INTERRUPTS_MASK_ALL, ®s->interrupt_disable); + + regval = readl(®s->control); + regval &= ~CDNS_I2C_CONTROL_HOLD; + regval |= CDNS_I2C_CONTROL_CLR_FIFO; + writel(regval, ®s->control); + + writel(0xFF, ®s->time_out); + + writel(0, ®s->transfer_size); + + regval = readl(®s->interrupt_status); + writel(regval, ®s->interrupt_status); + + regval = readl(®s->status); + writel(regval, ®s->status); + + writel(0, ®s->control); +} + +static void cdns_i2c_setup_master(struct cdns_i2c *i2c) +{ + u32 control; + + control = readl(&i2c->regs->control); + control |= CDNS_I2C_CONTROL_MS | CDNS_I2C_CONTROL_ACKEN | + CDNS_I2C_CONTROL_NEA; + writel(control, &i2c->regs->control); + + writel(CDNS_I2C_INTERRUPTS_MASK_MASTER, &i2c->regs->interrupt_enable); +} + +static void cdns_i2c_clear_hold_flag(struct cdns_i2c *i2c) +{ + u32 control; + + control = readl(&i2c->regs->control); + if (control & CDNS_I2C_CONTROL_HOLD) + writel(control & ~CDNS_I2C_CONTROL_HOLD, &i2c->regs->control); +} + +static bool cdns_i2c_is_busy(struct cdns_i2c *i2c) +{ + return readl(&i2c->regs->status) & CDNS_I2C_STATUS_BA; +} + +static int cdns_i2c_hw_error(struct cdns_i2c *i2c) +{ + u32 isr_status; + + isr_status = readl(&i2c->regs->interrupt_status); + + if (isr_status & CDNS_I2C_INTERRUPT_NACK) + return -EREMOTEIO; + + if (isr_status & + (CDNS_I2C_INTERRUPT_ARBLOST | CDNS_I2C_INTERRUPT_RXOVF)) + return -EAGAIN; + + return 0; +} + +static int cdns_i2c_wait_for_completion(struct cdns_i2c *i2c) +{ + int err; + u32 isr_status; + const u32 isr_mask = + (CDNS_I2C_INTERRUPT_COMP | CDNS_I2C_INTERRUPT_NACK | + CDNS_I2C_INTERRUPT_ARBLOST); + + err = readl_poll_timeout(&i2c->regs->interrupt_status, isr_status, + isr_status & isr_mask, I2C_TIMEOUT_US); + + if (err) + return -ETIMEDOUT; + + return cdns_i2c_hw_error(i2c); +} + +/* + * Find best clock divisors + * + * f = finput / (22 x (div_a + 1) x (div_b + 1)) + */ +static int cdns_i2c_calc_divs(u32 *f, u32 input_clk, u32 *a, u32 *b) +{ + ulong fscl = *f, best_fscl = *f, actual_fscl, temp; + uint div_a, div_b, calc_div_a = 0, calc_div_b = 0; + uint last_error, current_error; + + temp = input_clk / (22 * fscl); + + if (!temp || + (temp > (CDNS_I2C_CONTROL_DIV_A_MAX * CDNS_I2C_CONTROL_DIV_B_MAX))) + return -EINVAL; + + last_error = -1; + for (div_a = 0; div_a < CDNS_I2C_CONTROL_DIV_A_MAX; div_a++) { + div_b = DIV_ROUND_UP(input_clk, 22 * fscl * (div_a + 1)); + + if ((div_b < 1) || (div_b > CDNS_I2C_CONTROL_DIV_B_MAX)) + continue; + div_b--; + + actual_fscl = input_clk / (22 * (div_a + 1) * (div_b + 1)); + + if (actual_fscl > fscl) + continue; + + current_error = ((actual_fscl > fscl) ? (actual_fscl - fscl) : + (fscl - actual_fscl)); + + if (last_error > current_error) { + calc_div_a = div_a; + calc_div_b = div_b; + best_fscl = actual_fscl; + last_error = current_error; + } + } + + *a = calc_div_a; + *b = calc_div_b; + *f = best_fscl; + + return 0; +} + +static int cdns_i2c_set_clk(struct cdns_i2c *i2c, u32 scl_rate) +{ + u32 i2c_rate; + u32 control; + u32 div_a, div_b; + int err; + + i2c_rate = clk_get_rate(i2c->clk); + + err = cdns_i2c_calc_divs(&scl_rate, i2c_rate, &div_a, &div_b); + if (err) + return err; + + control = readl(&i2c->regs->control); + control &= ~(CDNS_I2C_CONTROL_DIV_B_MASK | CDNS_I2C_CONTROL_DIV_A_MASK); + control |= (div_b << CDNS_I2C_CONTROL_DIV_B_SHIFT) | + (div_a << CDNS_I2C_CONTROL_DIV_A_SHIFT); + writel(control, &i2c->regs->control); + + return err; +} + +static int cdns_i2c_read(struct cdns_i2c *i2c, uchar chip, uchar *buf, + uint buf_len) +{ + struct i2c_regs *regs = i2c->regs; + u32 control; + int err; + + control = readl(®s->control); + control |= CDNS_I2C_CONTROL_RW | CDNS_I2C_CONTROL_CLR_FIFO; + if (i2c->bus_hold_flag || (buf_len > CDNS_I2C_FIFO_DEPTH)) + control |= CDNS_I2C_CONTROL_HOLD; + writel(control, ®s->control); + + do { + uint bytes_to_receive; + u32 isr_status; + u64 start_time; + + isr_status = readl(®s->interrupt_status); + writel(isr_status, ®s->interrupt_status); + + if (buf_len > CDNS_I2C_TRANSFER_SIZE) + bytes_to_receive = CDNS_I2C_TRANSFER_SIZE; + else + bytes_to_receive = buf_len; + + buf_len -= bytes_to_receive; + + writel(bytes_to_receive, ®s->transfer_size); + writel(chip & CDNS_I2C_ADDRESS_MASK, ®s->address); + + start_time = get_time_ns(); + while (bytes_to_receive) { + err = cdns_i2c_hw_error(i2c); + if (err) + goto i2c_exit; + + if (is_timeout(start_time, + (I2C_TIMEOUT_US * USECOND))) { + err = -ETIMEDOUT; + goto i2c_exit; + } + + if (readl(®s->status) & CDNS_I2C_STATUS_RXDV) { + *buf++ = readl(®s->data); + bytes_to_receive--; + } + } + + } while (buf_len); + + err = cdns_i2c_wait_for_completion(i2c); + +i2c_exit: + if (!i2c->bus_hold_flag) + cdns_i2c_clear_hold_flag(i2c); + + return err; +} + +static int cdns_i2c_write(struct cdns_i2c *i2c, uchar chip, uchar *buf, + uint buf_len) +{ + struct i2c_regs *regs = i2c->regs; + u32 control; + u32 isr_status; + bool start_transfer; + int err; + + control = readl(®s->control); + control &= ~CDNS_I2C_CONTROL_RW; + control |= CDNS_I2C_CONTROL_CLR_FIFO; + if (i2c->bus_hold_flag || (buf_len > CDNS_I2C_FIFO_DEPTH)) + control |= CDNS_I2C_CONTROL_HOLD; + writel(control, ®s->control); + + isr_status = readl(®s->interrupt_status); + writel(isr_status, ®s->interrupt_status); + + start_transfer = true; + do { + uint bytes_to_send; + + bytes_to_send = + CDNS_I2C_FIFO_DEPTH - readl(®s->transfer_size); + + if (buf_len < bytes_to_send) + bytes_to_send = buf_len; + + buf_len -= bytes_to_send; + + while (bytes_to_send--) + writel(*buf++, ®s->data); + + if (start_transfer) { + writel(chip & CDNS_I2C_ADDRESS_MASK, ®s->address); + start_transfer = false; + } + + err = cdns_i2c_wait_for_completion(i2c); + if (err) + goto i2c_exit; + + } while (buf_len); + +i2c_exit: + if (!i2c->bus_hold_flag) + cdns_i2c_clear_hold_flag(i2c); + + return err; +} + +static int cdns_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg, + int nmsgs) +{ + struct cdns_i2c *i2c = container_of(adapter, struct cdns_i2c, adapter); + int i; + int err; + + if (cdns_i2c_is_busy(i2c)) + return -EBUSY; + + for (i = 0; i < nmsgs; i++) { + i2c->bus_hold_flag = i < (nmsgs - 1); + + if (msg->flags & I2C_M_RD) { + err = cdns_i2c_read(i2c, msg->addr, msg->buf, msg->len); + } else { + err = cdns_i2c_write(i2c, msg->addr, msg->buf, + msg->len); + } + + if (err) + return err; + + msg++; + } + + return nmsgs; +} + +static int cdns_i2c_probe(struct device_d *dev) +{ + struct device_node *np = dev->device_node; + struct resource *iores; + struct cdns_i2c *i2c; + u32 bitrate; + int err; + + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) + return PTR_ERR(iores); + + i2c = xzalloc(sizeof(*i2c)); + + dev->priv = i2c; + i2c->regs = IOMEM(iores->start); + + i2c->clk = clk_get(dev, NULL); + if (IS_ERR(i2c->clk)) + return PTR_ERR(i2c->clk); + + err = clk_enable(i2c->clk); + if (err) + return err; + + i2c->adapter.master_xfer = cdns_i2c_xfer; + i2c->adapter.nr = dev->id; + i2c->adapter.dev.parent = dev; + i2c->adapter.dev.device_node = np; + + cdns_i2c_reset_hardware(i2c); + + bitrate = 100000; + of_property_read_u32(np, "clock-frequency", &bitrate); + + err = cdns_i2c_set_clk(i2c, bitrate); + if (err) + return err; + + cdns_i2c_setup_master(i2c); + + return i2c_add_numbered_adapter(&i2c->adapter); +} + +static const struct of_device_id cdns_i2c_match[] = { + { .compatible = "cdns,i2c-r1p14" }, + {}, +}; + +static struct driver_d cdns_i2c_driver = { + .name = "cdns-i2c", + .of_compatible = cdns_i2c_match, + .probe = cdns_i2c_probe, +}; +coredevice_platform_driver(cdns_i2c_driver); diff --git a/drivers/i2c/busses/i2c-rockchip.c b/drivers/i2c/busses/i2c-rockchip.c index 4990735a4b..ca33905335 100644 --- a/drivers/i2c/busses/i2c-rockchip.c +++ b/drivers/i2c/busses/i2c-rockchip.c @@ -375,15 +375,17 @@ i2c_exit: return err; } -static int rockchip_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg, +static int rockchip_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int nmsgs) { struct rk_i2c *i2c = to_rk_i2c(adapter); struct device_d *dev = &adapter->dev; - int ret; + int i, ret = 0; dev_dbg(dev, "i2c_xfer: %d messages\n", nmsgs); - for (; nmsgs > 0; nmsgs--, msg++) { + for (i = 0; i < nmsgs; i++) { + struct i2c_msg *msg = &msgs[i]; + dev_dbg(dev, "i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len); if (msg->flags & I2C_M_RD) { ret = rk_i2c_read(i2c, msg->addr, 0, 0, msg->buf, @@ -395,14 +397,15 @@ static int rockchip_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg, if (ret) { dev_dbg(dev, "i2c_write: error sending: %pe\n", ERR_PTR(ret)); - return -EREMOTEIO; + ret = -EREMOTEIO; + break; } } rk_i2c_send_stop_bit(i2c); rk_i2c_disable(i2c); - return 0; + return ret < 0 ? ret : nmsgs; } static int rk_i2c_probe(struct device_d *dev) diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c index 445703ecd8..2d86d86334 100644 --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -83,7 +83,6 @@ struct rockchip_combphy_priv { struct regmap *pipe_grf; struct regmap *phy_grf; struct phy *phy; - struct reset_control *apb_rst; struct reset_control *phy_rst; const struct rockchip_combphy_cfg *cfg; }; @@ -317,17 +316,7 @@ static int rockchip_combphy_parse_dt(struct device_d *dev, param_write(priv->pipe_grf, &phy_cfg->grfcfg->pipe_sgmii_mac_sel, true); - priv->apb_rst = reset_control_get(dev, "combphy-apb"); - if (IS_ERR(priv->apb_rst)) { - ret = PTR_ERR(priv->apb_rst); - - if (ret != -EPROBE_DEFER) - dev_warn(dev, "failed to get apb reset\n"); - - return ret; - } - - priv->phy_rst = reset_control_get(dev, "combphy"); + priv->phy_rst = reset_control_get(dev, NULL); if (IS_ERR(priv->phy_rst)) { ret = PTR_ERR(priv->phy_rst); @@ -579,9 +568,9 @@ static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = { }; static const struct clk_bulk_data rk3568_clks[] = { - { .id = "refclk" }, - { .id = "apbclk" }, - { .id = "pipe_clk" }, + { .id = "ref" }, + { .id = "apb" }, + { .id = "pipe" }, }; static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index 464ae1aebc..f93a89ab95 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -366,11 +366,6 @@ static __maybe_unused struct ns16550_drvdata jz_drvdata = { .init_port = ns16550_jz_init_port, }; -static __maybe_unused struct ns16550_drvdata tegra_drvdata = { - .init_port = ns16550_serial_init_port, - .linux_console_name = "ttyS", -}; - static __maybe_unused struct ns16550_drvdata rpi_drvdata = { .init_port = rpi_init_port, .linux_console_name = "ttyS", @@ -528,6 +523,9 @@ static struct of_device_id ns16550_serial_dt_ids[] = { }, { .compatible = "marvell,armada-38x-uart", .data = &ns16550_drvdata, + }, { + .compatible = "nvidia,tegra20-uart", + .data = &ns16550_drvdata, }, #if IS_ENABLED(CONFIG_ARCH_OMAP) { @@ -541,12 +539,6 @@ static struct of_device_id ns16550_serial_dt_ids[] = { .data = &omap_drvdata, }, #endif -#if IS_ENABLED(CONFIG_ARCH_TEGRA) - { - .compatible = "nvidia,tegra20-uart", - .data = &tegra_drvdata, - }, -#endif #if IS_ENABLED(CONFIG_MACH_MIPS_XBURST) { .compatible = "ingenic,jz4740-uart", diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 7df7561718..8935feb97b 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -124,6 +124,12 @@ config SPI_NXP_FLEXSPI This controller does not support generic SPI messages and only supports the high-level SPI memory interface. +config SPI_SIFIVE + tristate "SiFive SPI controller" + depends on SOC_SIFIVE || COMPILE_TEST + help + This exposes the SPI controller IP from SiFive. + endif endmenu diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 64c8e2645a..3455eea869 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_DRIVER_SPI_DSPI) += dspi_spi.o obj-$(CONFIG_SPI_ZYNQ_QSPI) += zynq_qspi.o obj-$(CONFIG_SPI_NXP_FLEXSPI) += spi-nxp-fspi.o obj-$(CONFIG_DRIVER_SPI_STM32) += stm32_spi.o +obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c new file mode 100644 index 0000000000..713bcc0c3b --- /dev/null +++ b/drivers/spi/spi-sifive.c @@ -0,0 +1,521 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 SiFive, Inc. + * Copyright 2019 Bhargav Shah <bhargavshah1988@gmail.com> + * + * SiFive SPI controller driver (master mode only) + */ + +#include <common.h> +#include <linux/clk.h> +#include <driver.h> +#include <init.h> +#include <errno.h> +#include <linux/reset.h> +#include <spi/spi.h> +#include <linux/spi/spi-mem.h> +#include <linux/bitops.h> +#include <clock.h> +#include <gpio.h> +#include <of_gpio.h> +#include <linux/bitfield.h> +#include <linux/iopoll.h> +#include <linux/log2.h> + +#define SIFIVE_SPI_MAX_CS 32 + +#define SIFIVE_SPI_DEFAULT_DEPTH 8 +#define SIFIVE_SPI_DEFAULT_BITS 8 + +/* register offsets */ +#define SIFIVE_SPI_REG_SCKDIV 0x00 /* Serial clock divisor */ +#define SIFIVE_SPI_REG_SCKMODE 0x04 /* Serial clock mode */ +#define SIFIVE_SPI_REG_CSID 0x10 /* Chip select ID */ +#define SIFIVE_SPI_REG_CSDEF 0x14 /* Chip select default */ +#define SIFIVE_SPI_REG_CSMODE 0x18 /* Chip select mode */ +#define SIFIVE_SPI_REG_DELAY0 0x28 /* Delay control 0 */ +#define SIFIVE_SPI_REG_DELAY1 0x2c /* Delay control 1 */ +#define SIFIVE_SPI_REG_FMT 0x40 /* Frame format */ +#define SIFIVE_SPI_REG_TXDATA 0x48 /* Tx FIFO data */ +#define SIFIVE_SPI_REG_RXDATA 0x4c /* Rx FIFO data */ +#define SIFIVE_SPI_REG_TXMARK 0x50 /* Tx FIFO watermark */ +#define SIFIVE_SPI_REG_RXMARK 0x54 /* Rx FIFO watermark */ +#define SIFIVE_SPI_REG_FCTRL 0x60 /* SPI flash interface control */ +#define SIFIVE_SPI_REG_FFMT 0x64 /* SPI flash instruction format */ +#define SIFIVE_SPI_REG_IE 0x70 /* Interrupt Enable Register */ +#define SIFIVE_SPI_REG_IP 0x74 /* Interrupt Pendings Register */ + +/* sckdiv bits */ +#define SIFIVE_SPI_SCKDIV_DIV_MASK 0xfffU + +/* sckmode bits */ +#define SIFIVE_SPI_SCKMODE_PHA BIT(0) +#define SIFIVE_SPI_SCKMODE_POL BIT(1) +#define SIFIVE_SPI_SCKMODE_MODE_MASK (SIFIVE_SPI_SCKMODE_PHA | \ + SIFIVE_SPI_SCKMODE_POL) + +/* csmode bits */ +#define SIFIVE_SPI_CSMODE_MODE_AUTO 0U +#define SIFIVE_SPI_CSMODE_MODE_HOLD 2U +#define SIFIVE_SPI_CSMODE_MODE_OFF 3U + +/* delay0 bits */ +#define SIFIVE_SPI_DELAY0_CSSCK(x) ((u32)(x)) +#define SIFIVE_SPI_DELAY0_CSSCK_MASK 0xffU +#define SIFIVE_SPI_DELAY0_SCKCS(x) ((u32)(x) << 16) +#define SIFIVE_SPI_DELAY0_SCKCS_MASK (0xffU << 16) + +/* delay1 bits */ +#define SIFIVE_SPI_DELAY1_INTERCS(x) ((u32)(x)) +#define SIFIVE_SPI_DELAY1_INTERCS_MASK 0xffU +#define SIFIVE_SPI_DELAY1_INTERXFR(x) ((u32)(x) << 16) +#define SIFIVE_SPI_DELAY1_INTERXFR_MASK (0xffU << 16) + +/* fmt bits */ +#define SIFIVE_SPI_FMT_PROTO_SINGLE 0U +#define SIFIVE_SPI_FMT_PROTO_DUAL 1U +#define SIFIVE_SPI_FMT_PROTO_QUAD 2U +#define SIFIVE_SPI_FMT_PROTO_MASK 3U +#define SIFIVE_SPI_FMT_ENDIAN BIT(2) +#define SIFIVE_SPI_FMT_DIR BIT(3) +#define SIFIVE_SPI_FMT_LEN(x) ((u32)(x) << 16) +#define SIFIVE_SPI_FMT_LEN_MASK (0xfU << 16) + +/* txdata bits */ +#define SIFIVE_SPI_TXDATA_DATA_MASK 0xffU +#define SIFIVE_SPI_TXDATA_FULL BIT(31) + +/* rxdata bits */ +#define SIFIVE_SPI_RXDATA_DATA_MASK 0xffU +#define SIFIVE_SPI_RXDATA_EMPTY BIT(31) + +/* ie and ip bits */ +#define SIFIVE_SPI_IP_TXWM BIT(0) +#define SIFIVE_SPI_IP_RXWM BIT(1) + +/* format protocol */ +#define SIFIVE_SPI_PROTO_QUAD 4 /* 4 lines I/O protocol transfer */ +#define SIFIVE_SPI_PROTO_DUAL 2 /* 2 lines I/O protocol transfer */ +#define SIFIVE_SPI_PROTO_SINGLE 1 /* 1 line I/O protocol transfer */ + +#define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */ +#define SPI_XFER_END 0x02 /* Deassert CS after transfer */ + +struct sifive_spi { + struct spi_controller ctlr; + void __iomem *regs; /* base address of the registers */ + u32 fifo_depth; + u32 bits_per_word; + u32 cs_inactive; /* Level of the CS pins when inactive*/ + u32 freq; + u8 fmt_proto; +}; + +static inline struct sifive_spi *to_sifive_spi(struct spi_controller *ctlr) +{ + return container_of(ctlr, struct sifive_spi, ctlr); +} + +static void sifive_spi_prep_device(struct sifive_spi *spi, + struct spi_device *spi_dev) +{ + /* Update the chip select polarity */ + if (spi_dev->mode & SPI_CS_HIGH) + spi->cs_inactive &= ~BIT(spi_dev->chip_select); + else + spi->cs_inactive |= BIT(spi_dev->chip_select); + writel(spi->cs_inactive, spi->regs + SIFIVE_SPI_REG_CSDEF); + + /* Select the correct device */ + writel(spi_dev->chip_select, spi->regs + SIFIVE_SPI_REG_CSID); +} + +static void sifive_spi_set_cs(struct sifive_spi *spi, + struct spi_device *spi_dev) +{ + u32 cs_mode = SIFIVE_SPI_CSMODE_MODE_HOLD; + + if (spi_dev->mode & SPI_CS_HIGH) + cs_mode = SIFIVE_SPI_CSMODE_MODE_AUTO; + + writel(cs_mode, spi->regs + SIFIVE_SPI_REG_CSMODE); +} + +static void sifive_spi_clear_cs(struct sifive_spi *spi) +{ + writel(SIFIVE_SPI_CSMODE_MODE_AUTO, spi->regs + SIFIVE_SPI_REG_CSMODE); +} + +static void sifive_spi_prep_transfer(struct sifive_spi *spi, + struct spi_device *spi_dev, + u8 *rx_ptr) +{ + u32 cr; + + /* Modify the SPI protocol mode */ + cr = readl(spi->regs + SIFIVE_SPI_REG_FMT); + + /* Bits per word ? */ + cr &= ~SIFIVE_SPI_FMT_LEN_MASK; + cr |= SIFIVE_SPI_FMT_LEN(spi->bits_per_word); + + /* LSB first? */ + cr &= ~SIFIVE_SPI_FMT_ENDIAN; + if (spi_dev->mode & SPI_LSB_FIRST) + cr |= SIFIVE_SPI_FMT_ENDIAN; + + /* Number of wires ? */ + cr &= ~SIFIVE_SPI_FMT_PROTO_MASK; + switch (spi->fmt_proto) { + case SIFIVE_SPI_PROTO_QUAD: + cr |= SIFIVE_SPI_FMT_PROTO_QUAD; + break; + case SIFIVE_SPI_PROTO_DUAL: + cr |= SIFIVE_SPI_FMT_PROTO_DUAL; + break; + default: + cr |= SIFIVE_SPI_FMT_PROTO_SINGLE; + break; + } + + /* SPI direction in/out ? */ + cr &= ~SIFIVE_SPI_FMT_DIR; + if (!rx_ptr) + cr |= SIFIVE_SPI_FMT_DIR; + + writel(cr, spi->regs + SIFIVE_SPI_REG_FMT); +} + +static void sifive_spi_rx(struct sifive_spi *spi, u8 *rx_ptr) +{ + u32 data; + + do { + data = readl(spi->regs + SIFIVE_SPI_REG_RXDATA); + } while (data & SIFIVE_SPI_RXDATA_EMPTY); + + if (rx_ptr) + *rx_ptr = data & SIFIVE_SPI_RXDATA_DATA_MASK; +} + +static void sifive_spi_tx(struct sifive_spi *spi, const u8 *tx_ptr) +{ + u32 data; + u8 tx_data = (tx_ptr) ? *tx_ptr & SIFIVE_SPI_TXDATA_DATA_MASK : + SIFIVE_SPI_TXDATA_DATA_MASK; + + do { + data = readl(spi->regs + SIFIVE_SPI_REG_TXDATA); + } while (data & SIFIVE_SPI_TXDATA_FULL); + + writel(tx_data, spi->regs + SIFIVE_SPI_REG_TXDATA); +} + +static int sifive_spi_wait(struct sifive_spi *spi, u32 mask) +{ + u32 val; + + return readl_poll_timeout(spi->regs + SIFIVE_SPI_REG_IP, val, + (val & mask) == mask, 100 * USEC_PER_MSEC); +} + +static int sifive_spi_transfer_one(struct spi_device *spi_dev, unsigned int nbytes, + const void *dout, void *din) +{ + struct sifive_spi *spi = to_sifive_spi(spi_dev->controller); + const u8 *tx_ptr = dout; + u8 *rx_ptr = din; + int ret; + + sifive_spi_prep_transfer(spi, spi_dev, rx_ptr); + + while (nbytes) { + unsigned int n_words = min(nbytes, spi->fifo_depth); + unsigned int tx_words, rx_words; + + /* Enqueue n_words for transmission */ + for (tx_words = 0; tx_words < n_words; tx_words++) { + if (!tx_ptr) + sifive_spi_tx(spi, NULL); + else + sifive_spi_tx(spi, tx_ptr++); + } + + if (rx_ptr) { + /* Wait for transmission + reception to complete */ + writel(n_words - 1, spi->regs + SIFIVE_SPI_REG_RXMARK); + ret = sifive_spi_wait(spi, SIFIVE_SPI_IP_RXWM); + if (ret) + return ret; + + /* Read out all the data from the RX FIFO */ + for (rx_words = 0; rx_words < n_words; rx_words++) + sifive_spi_rx(spi, rx_ptr++); + } else { + /* Wait for transmission to complete */ + ret = sifive_spi_wait(spi, SIFIVE_SPI_IP_TXWM); + if (ret) + return ret; + } + + nbytes -= n_words; + } + + return 0; +} + +static int sifive_spi_transfer(struct spi_device *spi_dev, struct spi_message *msg) +{ + struct spi_controller *ctlr = spi_dev->controller; + struct sifive_spi *spi = to_sifive_spi(ctlr); + struct spi_transfer *t; + int ret = 0; + + if (list_empty(&msg->transfers)) + return 0; + + msg->actual_length = 0; + + sifive_spi_prep_device(spi, spi_dev); + sifive_spi_set_cs(spi, spi_dev); + + dev_dbg(ctlr->dev, "transfer start actual_length=%i\n", msg->actual_length); + list_for_each_entry(t, &msg->transfers, transfer_list) { + dev_dbg(ctlr->dev, " xfer %p: len %u tx %p rx %p\n", + t, t->len, t->tx_buf, t->rx_buf); + + ret = sifive_spi_transfer_one(spi_dev, t->len, + t->tx_buf, t->rx_buf); + if (ret < 0) + goto out; + msg->actual_length += t->len; + } + dev_dbg(ctlr->dev, "transfer done actual_length=%i\n", msg->actual_length); + +out: + sifive_spi_clear_cs(spi); + return ret; +} + +static int sifive_spi_exec_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + struct spi_device *spi_dev = mem->spi; + struct device_d *dev = &spi_dev->dev; + struct sifive_spi *spi = spi_controller_get_devdata(spi_dev->controller); + u8 opcode = op->cmd.opcode; + int ret; + + spi->fmt_proto = op->cmd.buswidth; + + sifive_spi_prep_device(spi, spi_dev); + sifive_spi_set_cs(spi, spi_dev); + + /* send the opcode */ + ret = sifive_spi_transfer_one(spi_dev, 1, &opcode, NULL); + if (ret < 0) { + dev_err(dev, "failed to xfer opcode\n"); + goto out; + } + + if (!op->addr.nbytes && !op->data.nbytes) + goto out; + + /* send the addr + dummy */ + if (op->addr.nbytes) { + int i, op_len = op->addr.nbytes + op->dummy.nbytes; + u8 *op_buf; + + op_buf = malloc(op_len); + if (!op_buf) { + ret = -ENOMEM; + goto out; + } + + /* fill address */ + for (i = 0; i < op->addr.nbytes; i++) + op_buf[i] = op->addr.val >> + (8 * (op->addr.nbytes - i - 1)); + + /* fill dummy */ + memset(op_buf + op->addr.nbytes, 0xff, op->dummy.nbytes); + + spi->fmt_proto = op->addr.buswidth; + + ret = sifive_spi_transfer_one(spi_dev, op_len, op_buf, NULL); + free(op_buf); + if (ret < 0) { + dev_err(dev, "failed to xfer addr + dummy\n"); + goto out; + } + } + + /* send/received the data */ + if (op->data.nbytes) { + const void *tx_buf = NULL; + void *rx_buf = NULL; + + if (op->data.dir == SPI_MEM_DATA_IN) + rx_buf = op->data.buf.in; + else + tx_buf = op->data.buf.out; + + spi->fmt_proto = op->data.buswidth; + + ret = sifive_spi_transfer_one(spi_dev, op->data.nbytes, + tx_buf, rx_buf); + if (ret) { + dev_err(dev, "failed to xfer data\n"); + goto out; + } + } + +out: + sifive_spi_clear_cs(spi); + return ret; +} + +static void sifive_spi_set_speed(struct sifive_spi *spi, uint speed) +{ + u32 scale; + + if (speed > spi->freq) + speed = spi->freq; + + /* Cofigure max speed */ + scale = (DIV_ROUND_UP(spi->freq >> 1, speed) - 1) + & SIFIVE_SPI_SCKDIV_DIV_MASK; + writel(scale, spi->regs + SIFIVE_SPI_REG_SCKDIV); +} + +static void sifive_spi_set_mode(struct sifive_spi *spi, uint mode) +{ + u32 cr; + + /* Switch clock mode bits */ + cr = readl(spi->regs + SIFIVE_SPI_REG_SCKMODE) & + ~SIFIVE_SPI_SCKMODE_MODE_MASK; + if (mode & SPI_CPHA) + cr |= SIFIVE_SPI_SCKMODE_PHA; + if (mode & SPI_CPOL) + cr |= SIFIVE_SPI_SCKMODE_POL; + + writel(cr, spi->regs + SIFIVE_SPI_REG_SCKMODE); +} + +static int sifive_spi_setup(struct spi_device *spi_dev) +{ + struct sifive_spi *spi = to_sifive_spi(spi_dev->controller); + + sifive_spi_set_mode(spi, spi_dev->mode); + sifive_spi_set_speed(spi, spi_dev->max_speed_hz); + + return 0; +} + +static void sifive_spi_init_hw(struct sifive_spi *spi) +{ + struct device_d *dev = spi->ctlr.dev; + u32 cs_bits; + + /* probe the number of CS lines */ + spi->cs_inactive = readl(spi->regs + SIFIVE_SPI_REG_CSDEF); + writel(0xffffffffU, spi->regs + SIFIVE_SPI_REG_CSDEF); + cs_bits = readl(spi->regs + SIFIVE_SPI_REG_CSDEF); + writel(spi->cs_inactive, spi->regs + SIFIVE_SPI_REG_CSDEF); + if (!cs_bits) { + dev_warn(dev, "Could not auto probe CS lines\n"); + return; + } + + spi->ctlr.num_chipselect = ilog2(cs_bits) + 1; + if (spi->ctlr.num_chipselect > SIFIVE_SPI_MAX_CS) { + dev_warn(dev, "Invalid number of spi slaves\n"); + return; + } + + /* Watermark interrupts are disabled by default */ + writel(0, spi->regs + SIFIVE_SPI_REG_IE); + + /* Default watermark FIFO threshold values */ + writel(1, spi->regs + SIFIVE_SPI_REG_TXMARK); + writel(0, spi->regs + SIFIVE_SPI_REG_RXMARK); + + /* Set CS/SCK Delays and Inactive Time to defaults */ + writel(SIFIVE_SPI_DELAY0_CSSCK(1) | SIFIVE_SPI_DELAY0_SCKCS(1), + spi->regs + SIFIVE_SPI_REG_DELAY0); + writel(SIFIVE_SPI_DELAY1_INTERCS(1) | SIFIVE_SPI_DELAY1_INTERXFR(0), + spi->regs + SIFIVE_SPI_REG_DELAY1); + + /* Exit specialized memory-mapped SPI flash mode */ + writel(0, spi->regs + SIFIVE_SPI_REG_FCTRL); +} + +static const struct spi_controller_mem_ops sifive_spi_mem_ops = { + .exec_op = sifive_spi_exec_op, +}; + +static void sifive_spi_dt_probe(struct sifive_spi *spi) +{ + struct device_node *node = spi->ctlr.dev->device_node; + + spi->fifo_depth = SIFIVE_SPI_DEFAULT_DEPTH; + of_property_read_u32(node, "sifive,fifo-depth", &spi->fifo_depth); + + spi->bits_per_word = SIFIVE_SPI_DEFAULT_BITS; + of_property_read_u32(node, "sifive,max-bits-per-word", &spi->bits_per_word); +} + +static int sifive_spi_probe(struct device_d *dev) +{ + struct sifive_spi *spi; + struct resource *iores; + struct spi_controller *ctlr; + struct clk *clkdev; + + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) + return PTR_ERR(iores); + + spi = xzalloc(sizeof(*spi)); + + spi->regs = IOMEM(iores->start); + if (!spi->regs) + return -ENODEV; + + ctlr = &spi->ctlr; + ctlr->dev = dev; + + ctlr->setup = sifive_spi_setup; + ctlr->transfer = sifive_spi_transfer; + ctlr->mem_ops = &sifive_spi_mem_ops; + + ctlr->bus_num = -1; + + spi_controller_set_devdata(ctlr, spi); + + sifive_spi_dt_probe(spi); + + clkdev = clk_get(dev, NULL); + if (IS_ERR(clkdev)) + return PTR_ERR(clkdev); + + spi->freq = clk_get_rate(clkdev); + + /* init the sifive spi hw */ + sifive_spi_init_hw(spi); + + return spi_register_master(ctlr); +} + +static const struct of_device_id sifive_spi_ids[] = { + { .compatible = "sifive,spi0" }, + { /* sentinel */ } +}; + +static struct driver_d sifive_spi_driver = { + .name = "sifive_spi", + .probe = sifive_spi_probe, + .of_compatible = sifive_spi_ids, +}; +coredevice_platform_driver(sifive_spi_driver); diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index fd0ec754e0..30aaef90ac 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -23,6 +23,11 @@ #define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */ +struct dwc3_match_data { + const struct clk_bulk_data *clks; + const int num_clks; +}; + /** * dwc3_get_dr_mode - Validates and sets dr_mode * @dwc: pointer to our context structure @@ -326,12 +331,6 @@ err0: return ret; } -static const struct clk_bulk_data dwc3_core_clks[] = { - { .id = "ref" }, - { .id = "bus_early" }, - { .id = "suspend" }, -}; - /* * dwc3_frame_length_adjustment - Adjusts frame length if required * @dwc3: Pointer to our controller context structure @@ -1098,20 +1097,23 @@ static void dwc3_coresoft_reset(struct dwc3 *dwc) static int dwc3_probe(struct device_d *dev) { + const struct dwc3_match_data *match; struct dwc3 *dwc; int ret; dwc = xzalloc(sizeof(*dwc)); dev->priv = dwc; - dwc->clks = xmemdup(dwc3_core_clks, sizeof(dwc3_core_clks)); + match = device_get_match_data(dev); + dwc->clks = xmemdup(match->clks, match->num_clks * + sizeof(struct clk_bulk_data)); dwc->dev = dev; dwc->regs = dev_get_mem_region(dwc->dev, 0) + DWC3_GLOBALS_REGS_START; dwc3_get_properties(dwc); if (dev->device_node) { - dwc->num_clks = ARRAY_SIZE(dwc3_core_clks); + dwc->num_clks = match->num_clks; if (of_find_property(dev->device_node, "clocks", NULL)) { ret = clk_bulk_get(dev, dwc->num_clks, dwc->clks); @@ -1176,12 +1178,40 @@ static void dwc3_remove(struct device_d *dev) clk_bulk_put(dwc->num_clks, dwc->clks); } +static const struct clk_bulk_data dwc3_core_clks[] = { + { .id = "ref" }, + { .id = "bus_early" }, + { .id = "suspend" }, +}; + +static const struct dwc3_match_data dwc3_default = { + .clks = dwc3_core_clks, + .num_clks = ARRAY_SIZE(dwc3_core_clks), +}; + +static const struct clk_bulk_data dwc3_core_clks_rk3568[] = { + { .id = "ref_clk" }, + { .id = "bus_clk" }, + { .id = "suspend_clk" }, +}; + +static const struct dwc3_match_data dwc3_rk3568 = { + .clks = dwc3_core_clks_rk3568, + .num_clks = ARRAY_SIZE(dwc3_core_clks_rk3568), +}; + static const struct of_device_id of_dwc3_match[] = { { - .compatible = "snps,dwc3" + .compatible = "snps,dwc3", + .data = &dwc3_default, + }, + { + .compatible = "synopsys,dwc3", + .data = &dwc3_default, }, { - .compatible = "synopsys,dwc3" + .compatible = "rockchip,rk3568-dwc3", + .data = &dwc3_rk3568, }, { }, }; diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index dcdc6c2135..a20b7bbee9 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -75,7 +75,7 @@ config DRIVER_VIDEO_S3C24XX config DRIVER_VIDEO_OMAP bool "OMAP framebuffer driver" - depends on ARCH_OMAP4 + depends on ARCH_OMAP4 || COMPILE_TEST help Add support for OMAP Display Controller. Currently this driver only supports OMAP4 SoCs in DISPC parallel mode on diff --git a/drivers/video/omap.c b/drivers/video/omap.c index 62c51a1dfc..ca41ab36fc 100644 --- a/drivers/video/omap.c +++ b/drivers/video/omap.c @@ -20,8 +20,7 @@ #include <clock.h> #include <linux/err.h> -#include <mach/omap4-silicon.h> -#include <mach/omap-fb.h> +#include <video/omap-fb.h> #include <mmu.h> diff --git a/images/Makefile.am33xx b/images/Makefile.am33xx index add676117c..a63def771e 100644 --- a/images/Makefile.am33xx +++ b/images/Makefile.am33xx @@ -26,6 +26,14 @@ FILE_barebox-am33xx-afi-gf-mlo.spi.img = start_am33xx_afi_gf_sram.pblb.mlospi am33xx-mlo-$(CONFIG_MACH_AFI_GF) += barebox-am33xx-afi-gf-mlo.img am33xx-mlospi-$(CONFIG_MACH_AFI_GF) += barebox-am33xx-afi-gf-mlo.spi.img +pblb-$(CONFIG_MACH_MYIRTECH_X335X) += start_am33xx_myirtech_sdram +FILE_barebox-am33xx-myirtech.img = start_am33xx_myirtech_sdram.pblb +am33xx-barebox-$(CONFIG_MACH_MYIRTECH_X335X) += barebox-am33xx-myirtech.img + +pblb-$(CONFIG_MACH_MYIRTECH_X335X) += start_am33xx_myirtech_sram +FILE_barebox-am33xx-myirtech-mlo.img = start_am33xx_myirtech_sram.pblb.mlo +am33xx-mlo-$(CONFIG_MACH_MYIRTECH_X335X) += barebox-am33xx-myirtech-mlo.img + pblb-$(CONFIG_MACH_PHYTEC_SOM_AM335X) += start_am33xx_phytec_phycore_nand_sdram FILE_barebox-am33xx-phytec-phycore.img = start_am33xx_phytec_phycore_nand_sdram.pblb am33xx-barebox-$(CONFIG_MACH_PHYTEC_SOM_AM335X) += barebox-am33xx-phytec-phycore.img diff --git a/include/ata_drive.h b/include/ata_drive.h index 6b8915c9cb..e11172ba39 100644 --- a/include/ata_drive.h +++ b/include/ata_drive.h @@ -67,7 +67,12 @@ enum { ATA_ID_MWDMA_MODES = 63, ATA_ID_PIO_MODES = 64, ATA_ID_QUEUE_DEPTH = 75, + ATA_ID_SATA_CAPAB_1 = 76, + ATA_ID_SATA_CAPAB_2 = 77, + ATA_ID_SATA_FEAT_SUPP = 78, + ATA_ID_SATA_FEAT_ENABLE = 79, ATA_ID_MAJOR_VER = 80, + ATA_ID_MINOR_VER = 81, ATA_ID_COMMAND_SET_1 = 82, ATA_ID_COMMAND_SET_2 = 83, ATA_ID_CFSSE = 84, diff --git a/arch/arm/mach-omap/include/mach/omap-fb.h b/include/video/omap-fb.h index f727164434..519460f0d5 100644 --- a/arch/arm/mach-omap/include/mach/omap-fb.h +++ b/include/video/omap-fb.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef H_BAREBOX_ARCH_ARM_MACH_OMAP_MACH_FB4_H -#define H_BAREBOX_ARCH_ARM_MACH_OMAP_MACH_FB4_H +#ifndef OMAP_FB_H +#define OMAP_FB_H #include <fb.h> @@ -42,8 +42,4 @@ struct omapfb_platform_data { void (*enable)(int p); }; -struct device_d; -struct device_d *omap_add_display(struct omapfb_platform_data *o_pdata); - - -#endif /* H_BAREBOX_ARCH_ARM_MACH_OMAP_MACH_FB4_H */ +#endif /* OMAP_FB_H */ |