svn commit: r358641 - in stable/12/sys: arm64/conf arm64/rockchip arm64/rockchip/clk conf

Emmanuel Vadot manu at FreeBSD.org
Wed Mar 4 20:48:32 UTC 2020


Author: manu
Date: Wed Mar  4 20:48:29 2020
New Revision: 358641
URL: https://svnweb.freebsd.org/changeset/base/358641

Log:
  MFC r354087, r354089, r354094, r354100, r354103, r354152
  
  r354087:
  arm64: rk3399: Add clock and gate for usb3 clocks
  
  r354089:
  arm64: rockchip: Add RK3399 TypeC phy driver
  
  This is a driver for the USB3 PHY present in the RK3399.
  While the phy support DP (Display Port) the driver doesn't has we have
  no driver to test this with for now.
  All the lane and pll configuration is just magic values from rockchip.
  While the manual have some info on those registers it's really hard to
  understand how to calculate those values (if there is a way).
  
  r354094 by peterj:
  Fix use of uninitialised variable.
  
  The RK805 regs array was being allocated before it's required size was
  known, causing the driver to use memory it didn't own.  That memory
  was subsequently allocated and used elsewhere causing later fatal data
  aborts in rk805_map().
  
  Whilst I'm here, add a sanity check to catch unsupported PMICs (this
  shouldn't ever get hit because the probe should have failed).
  
  Reviewed by:	manu
  Sponsored by:	Google
  
  r354100 by gonzo:
  arm64: rk3399: Add clock and gate for SPI clocks
  
  r354103 by gonzo:
  arm64: rk3399: add SPI driver and include it in GENERIC config
  
  SPI driver for Rockchip's RK3399 SoC. Implements PIO mode, CS selection,
  SPI mode and frequency configuration.
  
  Reviewed by:	manu
  Differential Revision:	https://reviews.freebsd.org/D22148
  
  r354152:
  arm64: rockchip: typec_phy: Rename timeout to retry
  
  Declare retry in the function scope.
  Rename it to retry as there is a timeout function which was
  causing to code to compile.
  
  Reported by:	jhibbits
  X-MFC-WITH:	r354089

Added:
  stable/12/sys/arm64/rockchip/rk_spi.c
     - copied unchanged from r354103, head/sys/arm64/rockchip/rk_spi.c
  stable/12/sys/arm64/rockchip/rk_typec_phy.c
     - copied, changed from r354089, head/sys/arm64/rockchip/rk_typec_phy.c
Modified:
  stable/12/sys/arm64/conf/GENERIC
  stable/12/sys/arm64/rockchip/clk/rk3399_cru.c
  stable/12/sys/arm64/rockchip/rk805.c
  stable/12/sys/conf/files.arm64
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/arm64/conf/GENERIC
==============================================================================
--- stable/12/sys/arm64/conf/GENERIC	Wed Mar  4 20:43:29 2020	(r358640)
+++ stable/12/sys/arm64/conf/GENERIC	Wed Mar  4 20:48:29 2020	(r358641)
@@ -180,6 +180,7 @@ device		pl011
 # USB support
 device		aw_usbphy		# Allwinner USB PHY
 device		rk_usb2phy		# Rockchip USB2PHY
+device		rk_typec_phy		# Rockchip TypeC PHY
 device		dwcotg			# DWC OTG controller
 device		ohci			# OHCI USB interface
 device		ehci			# EHCI USB interface (USB 2.0)
@@ -251,6 +252,7 @@ device		mv_thermal	# Marvell Thermal Sensor Controller
 # SPI
 device		spibus
 device		bcm2835_spi	# Broadcom BCM283x SPI bus
+device		rk_spi		# RockChip SPI controller
 
 # PWM
 device		pwm

Modified: stable/12/sys/arm64/rockchip/clk/rk3399_cru.c
==============================================================================
--- stable/12/sys/arm64/rockchip/clk/rk3399_cru.c	Wed Mar  4 20:43:29 2020	(r358640)
+++ stable/12/sys/arm64/rockchip/clk/rk3399_cru.c	Wed Mar  4 20:48:29 2020	(r358641)
@@ -54,9 +54,18 @@ __FBSDID("$FreeBSD$");
 
 #define	SCLK_USB2PHY0_REF	123
 #define	SCLK_USB2PHY1_REF	124
+#define	SCLK_USB3OTG0_REF	129
+#define	SCLK_USB3OTG1_REF	130
+#define	SCLK_USB3OTG0_SUSPEND	131
+#define	SCLK_USB3OTG1_SUSPEND	132
 #define	ACLK_EMMC_CORE		241
 #define	ACLK_EMMC_NOC		242
 #define	ACLK_EMMC_GRF		243
+#define	ACLK_USB3_NOC		245
+#define	ACLK_USB3OTG0		246
+#define	ACLK_USB3OTG1		247
+#define	ACLK_USB3_RKSOC_AXI_PERF	248
+#define	ACLK_USB3_GRF		249
 #define	PCLK_GPIO2		336
 #define	PCLK_GPIO3		337
 #define	PCLK_GPIO4		338
@@ -66,6 +75,11 @@ __FBSDID("$FreeBSD$");
 #define	PCLK_I2C5		344
 #define	PCLK_I2C6		345
 #define	PCLK_I2C7		346
+#define	PCLK_SPI0		347
+#define	PCLK_SPI1		348
+#define	PCLK_SPI2		349
+#define	PCLK_SPI4		350
+#define	PCLK_SPI5		351
 #define	HCLK_HOST0		456
 #define	HCLK_HOST0_ARB		457
 #define	HCLK_HOST1		458
@@ -103,6 +117,12 @@ static struct rk_cru_gate rk3399_gates[] = {
 	CRU_GATE(0, "hclk_perilp1_cpll_src", "cpll", 0x320, 1)
 	CRU_GATE(0, "hclk_perilp1_gpll_src", "gpll", 0x320, 0)
 
+	/* CRU_CLKGATE_CON12 */
+	CRU_GATE(SCLK_USB3OTG0_REF, "sclk_usb3otg0_ref", "xin24m", 0x330, 1)
+	CRU_GATE(SCLK_USB3OTG1_REF, "sclk_usb3otg1_ref", "xin24m", 0x330, 2)
+	CRU_GATE(SCLK_USB3OTG0_SUSPEND, "sclk_usb3otg0_suspend", "xin24m", 0x330, 3)
+	CRU_GATE(SCLK_USB3OTG1_SUSPEND, "sclk_usb3otg1_suspend", "xin24m", 0x330, 4)
+
 	/* CRU_CLKGATE_CON20 */
 	CRU_GATE(HCLK_HOST0, "hclk_host0", "hclk_perihp", 0x350, 5)
 	CRU_GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_perihp", 0x350, 6)
@@ -117,6 +137,19 @@ static struct rk_cru_gate rk3399_gates[] = {
 	CRU_GATE(PCLK_I2C2, "pclk_rki2c2", "pclk_perilp1", 0x358, 9)
 	CRU_GATE(PCLK_I2C3, "pclk_rki2c3", "pclk_perilp1", 0x358, 10)
 
+	/* CRU_CLKGATE_CON23 */
+	CRU_GATE(PCLK_SPI0, "pclk_spi0", "pclk_perilp1", 0x35C, 10)
+	CRU_GATE(PCLK_SPI1, "pclk_spi1", "pclk_perilp1", 0x35C, 11)
+	CRU_GATE(PCLK_SPI2, "pclk_spi2", "pclk_perilp1", 0x35C, 12)
+	CRU_GATE(PCLK_SPI4, "pclk_spi4", "pclk_perilp1", 0x35C, 13)
+
+	/* CRU_CLKGATE_CON30 */
+	CRU_GATE(ACLK_USB3_NOC, "aclk_usb3_noc", "aclk_usb3", 0x378, 0)
+	CRU_GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb3", 0x378, 1)
+	CRU_GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_usb3", 0x378, 2)
+	CRU_GATE(ACLK_USB3_RKSOC_AXI_PERF, "aclk_usb3_rksoc_axi_perf", "aclk_usb3", 0x378, 3)
+	CRU_GATE(ACLK_USB3_GRF, "aclk_usb3_grf", "aclk_usb3", 0x378, 4)
+
 	/* CRU_CLKGATE_CON31 */
 	CRU_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_alive", 0x37c, 3)
 	CRU_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_alive", 0x37c, 4)
@@ -129,6 +162,9 @@ static struct rk_cru_gate rk3399_gates[] = {
 
 	/* CRU_CLKGATE_CON33 */
 	CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sd", 0x384, 8)
+
+	/* CRU_CLKGATE_CON34 */
+	CRU_GATE(PCLK_SPI4, "pclk_spi5", "pclk_perilp1", 0x388, 5)
 };
 
 
@@ -1066,6 +1102,32 @@ static struct rk_clk_composite_def pclk_perilp1 = {
 	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
 };
 
+/* USB3 clock */
+
+#define	ACLK_USB3	244
+static const char *aclk_usb3_parents[] = {"cpll", "gpll", "npll", "npll"};
+static struct rk_clk_composite_def aclk_usb3 = {
+	.clkdef = {
+		.id = ACLK_USB3,
+		.name = "aclk_usb3",
+		.parent_names = aclk_usb3_parents,
+		.parent_cnt = nitems(aclk_usb3_parents),
+	},
+	/* CRU_CLKSET_CON39 */
+	.muxdiv_offset = 0x19C,
+	.mux_shift = 6,
+	.mux_width = 2,
+
+	.div_shift = 0,
+	.div_width = 5,
+
+	/* CRU_CLKGATE_CON12 */
+	.gate_offset = 0x330,
+	.gate_shift = 0,
+
+	.flags = RK_CLK_COMPOSITE_HAVE_GATE,
+};
+
 /*
  * i2c
  */
@@ -1210,7 +1272,236 @@ static struct rk_clk_composite_def i2c7 = {
 	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
 };
 
+/* USB3 */
+
+#define	SCLK_UPHY0_TCPDPHY_REF	125
+#define	SCLK_UPHY0_TCPDCORE	126
+
+/* Missing xin32k exported by rk808 */
+static const char *uphy0_tcpdphy_ref_parents[] = {"xin24m"};
+
+static struct rk_clk_composite_def uphy0_tcpdphy_ref = {
+	.clkdef = {
+		.id = SCLK_UPHY0_TCPDPHY_REF,
+		.name = "uphy0_tcpdphy_ref",
+		.parent_names = uphy0_tcpdphy_ref_parents,
+		.parent_cnt = nitems(uphy0_tcpdphy_ref_parents),
+	},
+	/* CRU_CLKSET_CON64 */
+	.muxdiv_offset = 0x0200,
+	.mux_shift = 15,
+	.mux_width = 1,
+
+	.div_shift = 8,
+	.div_width = 5,
+
+	/* CRU_CLKGATE_CON13 */
+	.gate_offset = 0x0334,
+	.gate_shift = 4,
+
+	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
+};
+
+/* Missing xin32k exported by rk808 */
+static const char *uphy0_tcpdcore_parents[] = {"xin24m", "xin24m", "cpll", "gpll"};
+
+static struct rk_clk_composite_def uphy0_tcpdcore = {
+	.clkdef = {
+		.id = SCLK_UPHY0_TCPDCORE,
+		.name = "uphy0_tcpdcore",
+		.parent_names = uphy0_tcpdcore_parents,
+		.parent_cnt = nitems(uphy0_tcpdcore_parents),
+	},
+	/* CRU_CLKSET_CON64 */
+	.muxdiv_offset = 0x0200,
+	.mux_shift = 6,
+	.mux_width = 2,
+
+	.div_shift = 0,
+	.div_width = 5,
+
+	/* CRU_CLKGATE_CON13 */
+	.gate_offset = 0x0334,
+	.gate_shift = 5,
+
+	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
+};
+
+#define	SCLK_UPHY1_TCPDPHY_REF	127
+#define	SCLK_UPHY1_TCPDCORE	128
+
+/* Missing xin32k exported by rk808 */
+static const char *uphy1_tcpdphy_ref_parents[] = {"xin24m"};
+
+static struct rk_clk_composite_def uphy1_tcpdphy_ref = {
+	.clkdef = {
+		.id = SCLK_UPHY1_TCPDPHY_REF,
+		.name = "uphy1_tcpdphy_ref",
+		.parent_names = uphy1_tcpdphy_ref_parents,
+		.parent_cnt = nitems(uphy1_tcpdphy_ref_parents),
+	},
+	/* CRU_CLKSET_CON65 */
+	.muxdiv_offset = 0x0204,
+	.mux_shift = 15,
+	.mux_width = 1,
+
+	.div_shift = 8,
+	.div_width = 5,
+
+	/* CRU_CLKGATE_CON13 */
+	.gate_offset = 0x0334,
+	.gate_shift = 6,
+
+	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
+};
+
+/* Missing xin32k exported by rk808 */
+static const char *uphy1_tcpdcore_parents[] = {"xin24m", "xin24m", "cpll", "gpll"};
+
+static struct rk_clk_composite_def uphy1_tcpdcore = {
+	.clkdef = {
+		.id = SCLK_UPHY1_TCPDCORE,
+		.name = "uphy1_tcpdcore",
+		.parent_names = uphy1_tcpdcore_parents,
+		.parent_cnt = nitems(uphy1_tcpdcore_parents),
+	},
+	/* CRU_CLKSET_CON65 */
+	.muxdiv_offset = 0x0204,
+	.mux_shift = 6,
+	.mux_width = 2,
+
+	.div_shift = 0,
+	.div_width = 5,
+
+	/* CRU_CLKGATE_CON13 */
+	.gate_offset = 0x0334,
+	.gate_shift = 7,
+
+	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
+};
+
 /*
+ * spi
+ */
+static const char *spi_parents[] = {"cpll", "gpll"};
+
+#define	SCLK_SPI0	71
+#define	SCLK_SPI1	72
+#define	SCLK_SPI2	73
+#define	SCLK_SPI4	74
+#define	SCLK_SPI5	75
+
+static struct rk_clk_composite_def spi0 = {
+	.clkdef = {
+		.id = SCLK_SPI0,
+		.name = "clk_spi0",
+		.parent_names = spi_parents,
+		.parent_cnt = nitems(spi_parents),
+	},
+	/* CRU_CLKSEL_CON59 */
+	.muxdiv_offset = 0x01ec,
+	.mux_shift = 7,
+	.mux_width = 1,
+
+	.div_shift = 0,
+	.div_width = 7,
+
+	/* CRU_CLKGATE_CON9 */
+	.gate_offset = 0x0324,
+	.gate_shift = 12,
+
+	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
+};
+
+static struct rk_clk_composite_def spi1 = {
+	.clkdef = {
+		.id = SCLK_SPI1,
+		.name = "clk_spi1",
+		.parent_names = spi_parents,
+		.parent_cnt = nitems(spi_parents),
+	},
+	/* CRU_CLKSEL_CON59 */
+	.muxdiv_offset = 0x01ec,
+	.mux_shift = 15,
+	.mux_width = 1,
+
+	.div_shift = 8,
+	.div_width = 7,
+
+	/* CRU_CLKGATE_CON9 */
+	.gate_offset = 0x0324,
+	.gate_shift = 13,
+
+	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
+};
+
+static struct rk_clk_composite_def spi2 = {
+	.clkdef = {
+		.id = SCLK_SPI2,
+		.name = "clk_spi2",
+		.parent_names = spi_parents,
+		.parent_cnt = nitems(spi_parents),
+	},
+	/* CRU_CLKSEL_CON60 */
+	.muxdiv_offset = 0x01f0,
+	.mux_shift = 7,
+	.mux_width = 1,
+
+	.div_shift = 0,
+	.div_width = 7,
+
+	/* CRU_CLKGATE_CON9 */
+	.gate_offset = 0x0324,
+	.gate_shift = 14,
+
+	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
+};
+
+static struct rk_clk_composite_def spi4 = {
+	.clkdef = {
+		.id = SCLK_SPI4,
+		.name = "clk_spi4",
+		.parent_names = spi_parents,
+		.parent_cnt = nitems(spi_parents),
+	},
+	/* CRU_CLKSEL_CON60 */
+	.muxdiv_offset = 0x01f0,
+	.mux_shift = 15,
+	.mux_width = 1,
+
+	.div_shift = 8,
+	.div_width = 7,
+
+	/* CRU_CLKGATE_CON9 */
+	.gate_offset = 0x0324,
+	.gate_shift = 15,
+
+	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
+};
+
+static struct rk_clk_composite_def spi5 = {
+	.clkdef = {
+		.id = SCLK_SPI5,
+		.name = "clk_spi5",
+		.parent_names = spi_parents,
+		.parent_cnt = nitems(spi_parents),
+	},
+	/* CRU_CLKSEL_CON58 */
+	.muxdiv_offset = 0x01e8,
+	.mux_shift = 15,
+	.mux_width = 1,
+
+	.div_shift = 8,
+	.div_width = 7,
+
+	/* CRU_CLKGATE_CON13 */
+	.gate_offset = 0x0334,
+	.gate_shift = 13,
+
+	.flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
+};
+
+/*
  * ARM CPU clocks (LITTLE and big)
  */
 #define ARMCLKL				8
@@ -1593,6 +1884,10 @@ static struct rk_clk rk3399_clks[] = {
 	},
 	{
 		.type = RK_CLK_COMPOSITE,
+		.clk.composite = &aclk_usb3,
+	},
+	{
+		.type = RK_CLK_COMPOSITE,
 		.clk.composite = &i2c1,
 	},
 	{
@@ -1614,6 +1909,43 @@ static struct rk_clk rk3399_clks[] = {
 	{
 		.type = RK_CLK_COMPOSITE,
 		.clk.composite = &i2c7,
+	},
+	{
+		.type = RK_CLK_COMPOSITE,
+		.clk.composite = &uphy0_tcpdphy_ref,
+	},
+	{
+		.type = RK_CLK_COMPOSITE,
+		.clk.composite = &uphy0_tcpdcore,
+	},
+	{
+		.type = RK_CLK_COMPOSITE,
+		.clk.composite = &uphy1_tcpdphy_ref,
+	},
+	{
+		.type = RK_CLK_COMPOSITE,
+		.clk.composite = &uphy1_tcpdcore,
+	},
+
+	{
+		.type = RK_CLK_COMPOSITE,
+		.clk.composite = &spi0,
+	},
+	{
+		.type = RK_CLK_COMPOSITE,
+		.clk.composite = &spi1,
+	},
+	{
+		.type = RK_CLK_COMPOSITE,
+		.clk.composite = &spi2,
+	},
+	{
+		.type = RK_CLK_COMPOSITE,
+		.clk.composite = &spi4,
+	},
+	{
+		.type = RK_CLK_COMPOSITE,
+		.clk.composite = &spi5,
 	},
 
 	{

Modified: stable/12/sys/arm64/rockchip/rk805.c
==============================================================================
--- stable/12/sys/arm64/rockchip/rk805.c	Wed Mar  4 20:43:29 2020	(r358640)
+++ stable/12/sys/arm64/rockchip/rk805.c	Wed Mar  4 20:48:29 2020	(r358641)
@@ -468,9 +468,6 @@ rk805_attach(device_t dev)
 	if (config_intrhook_establish(&sc->intr_hook) != 0)
 		return (ENOMEM);
 
-	sc->regs = malloc(sizeof(struct rk805_reg_sc *) * sc->nregs,
-	    M_RK805_REG, M_WAITOK | M_ZERO);
-
 	sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
 	switch (sc->type) {
 	case RK805:
@@ -481,7 +478,13 @@ rk805_attach(device_t dev)
 		regdefs = rk808_regdefs;
 		sc->nregs = nitems(rk808_regdefs);
 		break;
+	default:
+		device_printf(dev, "Unknown type %d\n", sc->type);
+		return (ENXIO);
 	}
+
+	sc->regs = malloc(sizeof(struct rk805_reg_sc *) * sc->nregs,
+	    M_RK805_REG, M_WAITOK | M_ZERO);
 
 	rnode = ofw_bus_find_child(ofw_bus_get_node(dev), "regulators");
 	if (rnode > 0) {

Copied: stable/12/sys/arm64/rockchip/rk_spi.c (from r354103, head/sys/arm64/rockchip/rk_spi.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/12/sys/arm64/rockchip/rk_spi.c	Wed Mar  4 20:48:29 2020	(r358641, copy of r354103, head/sys/arm64/rockchip/rk_spi.c)
@@ -0,0 +1,483 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2019 Oleksandr Tymoshenko <gonzo at FreeBSD.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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/resource.h>
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/spibus/spi.h>
+#include <dev/spibus/spibusvar.h>
+
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+
+#include "spibus_if.h"
+
+#define	RK_SPI_CTRLR0		0x0000
+#define		CTRLR0_OPM_MASTER	(0 << 20)
+#define		CTRLR0_XFM_TR		(0 << 18)
+#define		CTRLR0_FRF_MOTO		(0 << 16)
+#define		CTRLR0_BHT_8BIT		(1 << 13)
+#define		CTRLR0_EM_BIG		(1 << 11)
+#define		CTRLR0_SSD_ONE		(1 << 10)
+#define		CTRLR0_SCPOL		(1 <<  7)
+#define		CTRLR0_SCPH		(1 <<  6)
+#define		CTRLR0_DFS_8BIT		(1 <<  0)
+#define	RK_SPI_CTRLR1		0x0004
+#define	RK_SPI_ENR		0x0008
+#define	RK_SPI_SER		0x000c
+#define	RK_SPI_BAUDR		0x0010
+#define	RK_SPI_TXFTLR		0x0014
+#define	RK_SPI_RXFTLR		0x0018
+#define	RK_SPI_TXFLR		0x001c
+#define	RK_SPI_RXFLR		0x0020
+#define	RK_SPI_SR		0x0024
+#define		SR_BUSY			(1 <<  0)
+#define	RK_SPI_IPR		0x0028
+#define	RK_SPI_IMR		0x002c
+#define		IMR_RFFIM		(1 <<  4)
+#define		IMR_TFEIM		(1 <<  0)
+#define	RK_SPI_ISR		0x0030
+#define		ISR_RFFIS		(1 <<  4)
+#define		ISR_TFEIS		(1 <<  0)
+#define	RK_SPI_RISR		0x0034
+#define	RK_SPI_ICR		0x0038
+#define	RK_SPI_DMACR		0x003c
+#define	RK_SPI_DMATDLR		0x0040
+#define	RK_SPI_DMARDLR		0x0044
+#define	RK_SPI_TXDR		0x0400
+#define	RK_SPI_RXDR		0x0800
+
+#define	CS_MAX			1
+
+static struct ofw_compat_data compat_data[] = {
+	{ "rockchip,rk3399-spi",		1 },
+	{ NULL,					0 }
+};
+
+static struct resource_spec rk_spi_spec[] = {
+	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
+	{ SYS_RES_IRQ,		0,	RF_ACTIVE | RF_SHAREABLE },
+	{ -1, 0 }
+};
+
+struct rk_spi_softc {
+	device_t	dev;
+	device_t	spibus;
+	struct resource	*res[2];
+	struct mtx	mtx;
+	clk_t		clk_apb;
+	clk_t		clk_spi;
+	void *		intrhand;
+	int		transfer;
+	uint32_t	fifo_size;
+	uint64_t	max_freq;
+
+	uint32_t	intreg;
+	uint8_t		*rxbuf;
+	uint32_t	rxidx;
+	uint8_t		*txbuf;
+	uint32_t	txidx;
+	uint32_t	txlen;
+	uint32_t	rxlen;
+};
+
+#define	RK_SPI_LOCK(sc)			mtx_lock(&(sc)->mtx)
+#define	RK_SPI_UNLOCK(sc)		mtx_unlock(&(sc)->mtx)
+#define	RK_SPI_READ_4(sc, reg)		bus_read_4((sc)->res[0], (reg))
+#define	RK_SPI_WRITE_4(sc, reg, val)	bus_write_4((sc)->res[0], (reg), (val))
+
+static int rk_spi_probe(device_t dev);
+static int rk_spi_attach(device_t dev);
+static int rk_spi_detach(device_t dev);
+static void rk_spi_intr(void *arg);
+
+static void
+rk_spi_enable_chip(struct rk_spi_softc *sc, int enable)
+{
+
+	RK_SPI_WRITE_4(sc, RK_SPI_ENR, enable ? 1 : 0);
+}
+
+static int
+rk_spi_set_cs(struct rk_spi_softc *sc, uint32_t cs, bool active)
+{
+	uint32_t reg;
+
+	if (cs & SPIBUS_CS_HIGH) {
+		device_printf(sc->dev, "SPIBUS_CS_HIGH is not supported\n");
+		return (EINVAL);
+	}
+
+	if (cs > CS_MAX)
+		return (EINVAL);
+
+	reg = RK_SPI_READ_4(sc, RK_SPI_SER);
+	if (active)
+		reg |= (1 << cs);
+	else
+		reg &= ~(1 << cs);
+	RK_SPI_WRITE_4(sc, RK_SPI_SER, reg);
+
+	return (0);
+}
+
+static void
+rk_spi_hw_setup(struct rk_spi_softc *sc, uint32_t mode, uint32_t freq)
+{
+	uint32_t cr0;
+	uint32_t div;
+
+	cr0 =  CTRLR0_OPM_MASTER | CTRLR0_XFM_TR | CTRLR0_FRF_MOTO |
+	    CTRLR0_BHT_8BIT | CTRLR0_EM_BIG | CTRLR0_SSD_ONE |
+	    CTRLR0_DFS_8BIT;
+
+	if (mode & SPIBUS_MODE_CPHA)
+		cr0 |= CTRLR0_SCPH;
+	if (mode & SPIBUS_MODE_CPOL)
+		cr0 |= CTRLR0_SCPOL;
+
+	/* minimum divider is 2 */
+	if (sc->max_freq < freq*2) {
+		clk_set_freq(sc->clk_spi, 2 * freq, CLK_SET_ROUND_DOWN);
+		clk_get_freq(sc->clk_spi, &sc->max_freq);
+	}
+
+	div = ((sc->max_freq + freq - 1) / freq);
+	div = (div + 1) & 0xfffe;
+	RK_SPI_WRITE_4(sc, RK_SPI_BAUDR, div);
+
+	RK_SPI_WRITE_4(sc, RK_SPI_CTRLR0, cr0);
+}
+
+static uint32_t
+rk_spi_fifo_size(struct rk_spi_softc *sc)
+{
+	uint32_t txftlr, reg;
+
+	for (txftlr = 2; txftlr < 32; txftlr++) {
+		RK_SPI_WRITE_4(sc, RK_SPI_TXFTLR, txftlr);
+		reg = RK_SPI_READ_4(sc, RK_SPI_TXFTLR);
+		if (reg != txftlr)
+			break;
+	}
+	RK_SPI_WRITE_4(sc, RK_SPI_TXFTLR, 0);
+
+	if (txftlr == 31)
+		return 0;
+
+	return txftlr;
+}
+
+static void
+rk_spi_empty_rxfifo(struct rk_spi_softc *sc)
+{
+	uint32_t rxlevel;
+	rxlevel = RK_SPI_READ_4(sc, RK_SPI_RXFLR);
+	while (sc->rxidx < sc->rxlen &&
+	    (rxlevel-- > 0)) {
+		sc->rxbuf[sc->rxidx++] = (uint8_t)RK_SPI_READ_4(sc, RK_SPI_RXDR);
+	}
+}
+
+static void
+rk_spi_fill_txfifo(struct rk_spi_softc *sc)
+{
+	uint32_t txlevel;
+	txlevel = RK_SPI_READ_4(sc, RK_SPI_TXFLR);
+	int cnt = 0;
+
+	while (sc->txidx < sc->txlen && txlevel < sc->fifo_size) {
+		RK_SPI_WRITE_4(sc, RK_SPI_TXDR, sc->txbuf[sc->txidx++]);
+		txlevel++;
+		cnt++;
+	}
+
+	if (sc->txidx != sc->txlen)
+		sc->intreg |= (IMR_TFEIM  | IMR_RFFIM);
+}
+
+static int
+rk_spi_xfer_buf(struct rk_spi_softc *sc, void *rxbuf, void *txbuf, uint32_t len)
+{
+	int err;
+
+	if (len == 0)
+		return (0);
+
+	sc->rxbuf = rxbuf;
+	sc->rxlen = len;
+	sc->rxidx = 0;
+	sc->txbuf = txbuf;
+	sc->txlen = len;
+	sc->txidx = 0;
+	sc->intreg = 0;
+	rk_spi_fill_txfifo(sc);
+
+	RK_SPI_WRITE_4(sc, RK_SPI_IMR, sc->intreg);
+
+	err = 0;
+	while (err == 0 && sc->intreg != 0)
+		err = msleep(sc, &sc->mtx, 0, "rk_spi", 10 * hz);
+
+	while (err == 0 && sc->rxidx != sc->txidx) {
+		/* read residual data from RX fifo */
+		rk_spi_empty_rxfifo(sc);
+	}
+
+	if (sc->rxidx != sc->rxlen || sc->txidx != sc->txlen)
+		err = EIO;
+
+	return (err);
+}
+
+static int
+rk_spi_probe(device_t dev)
+{
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
+		return (ENXIO);
+
+	device_set_desc(dev, "Rockchip SPI");
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+rk_spi_attach(device_t dev)
+{
+	struct rk_spi_softc *sc;
+	int error;
+
+	sc = device_get_softc(dev);
+	sc->dev = dev;
+
+	mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+
+	if (bus_alloc_resources(dev, rk_spi_spec, sc->res) != 0) {
+		device_printf(dev, "cannot allocate resources for device\n");
+		error = ENXIO;
+		goto fail;
+	}
+
+	if (bus_setup_intr(dev, sc->res[1],
+	    INTR_TYPE_MISC | INTR_MPSAFE, NULL, rk_spi_intr, sc,
+	    &sc->intrhand)) {
+		bus_release_resources(dev, rk_spi_spec, sc->res);
+		device_printf(dev, "cannot setup interrupt handler\n");
+		return (ENXIO);
+	}
+
+	/* Activate the module clock. */
+	error = clk_get_by_ofw_name(dev, 0, "apb_pclk", &sc->clk_apb);
+	if (error != 0) {
+		device_printf(dev, "cannot get apb_pclk clock\n");
+		goto fail;
+	}
+	error = clk_get_by_ofw_name(dev, 0, "spiclk", &sc->clk_spi);
+	if (error != 0) {
+		device_printf(dev, "cannot get spiclk clock\n");
+		goto fail;
+	}
+	error = clk_enable(sc->clk_apb);
+	if (error != 0) {
+		device_printf(dev, "cannot enable ahb clock\n");
+		goto fail;
+	}
+	error = clk_enable(sc->clk_spi);
+	if (error != 0) {
+		device_printf(dev, "cannot enable spiclk clock\n");
+		goto fail;
+	}
+	clk_get_freq(sc->clk_spi, &sc->max_freq);
+
+	sc->fifo_size = rk_spi_fifo_size(sc);
+	if (sc->fifo_size == 0) {
+		device_printf(dev, "failed to get fifo size\n");
+		goto fail;
+	}
+
+	sc->spibus = device_add_child(dev, "spibus", -1);
+
+	RK_SPI_WRITE_4(sc, RK_SPI_IMR, 0);
+	RK_SPI_WRITE_4(sc, RK_SPI_TXFTLR, sc->fifo_size/2 - 1);
+	RK_SPI_WRITE_4(sc, RK_SPI_RXFTLR, sc->fifo_size/2 - 1);
+
+	return (bus_generic_attach(dev));
+
+fail:
+	rk_spi_detach(dev);
+	return (error);
+}
+
+static int
+rk_spi_detach(device_t dev)
+{
+	struct rk_spi_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	bus_generic_detach(sc->dev);
+	if (sc->spibus != NULL)
+		device_delete_child(dev, sc->spibus);
+
+	if (sc->clk_spi != NULL)
+		clk_release(sc->clk_spi);
+	if (sc->clk_apb)
+		clk_release(sc->clk_apb);
+
+	if (sc->intrhand != NULL)
+		bus_teardown_intr(sc->dev, sc->res[1], sc->intrhand);
+
+	bus_release_resources(dev, rk_spi_spec, sc->res);
+	mtx_destroy(&sc->mtx);
+
+	return (0);
+}
+
+static void
+rk_spi_intr(void *arg)
+{
+	struct rk_spi_softc *sc;
+	uint32_t intreg, isr;
+
+	sc = arg;
+
+	RK_SPI_LOCK(sc);
+	intreg = RK_SPI_READ_4(sc, RK_SPI_IMR);
+	isr = RK_SPI_READ_4(sc, RK_SPI_ISR);
+	RK_SPI_WRITE_4(sc, RK_SPI_ICR, isr);
+
+	if (isr & ISR_RFFIS)
+		rk_spi_empty_rxfifo(sc);
+
+	if (isr & ISR_TFEIS)
+		rk_spi_fill_txfifo(sc);
+
+	/* no bytes left, disable interrupt */
+	if (sc->txidx == sc->txlen) {
+		sc->intreg = 0;
+		wakeup(sc);
+	}
+
+	if (sc->intreg != intreg) {
+		(void)RK_SPI_WRITE_4(sc, RK_SPI_IMR, sc->intreg);
+		(void)RK_SPI_READ_4(sc, RK_SPI_IMR);
+	}
+
+	RK_SPI_UNLOCK(sc);
+}
+
+static phandle_t
+rk_spi_get_node(device_t bus, device_t dev)
+{
+
+	return ofw_bus_get_node(bus);
+}
+
+static int
+rk_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
+{
+	struct rk_spi_softc *sc;
+	uint32_t cs, mode, clock;
+	int err = 0;
+
+	sc = device_get_softc(dev);
+
+	spibus_get_cs(child, &cs);
+	spibus_get_clock(child, &clock);
+	spibus_get_mode(child, &mode);
+
+	RK_SPI_LOCK(sc);
+	rk_spi_hw_setup(sc, mode, clock);
+	rk_spi_enable_chip(sc, 1);
+	err = rk_spi_set_cs(sc, cs, true);
+	if (err != 0) {
+		rk_spi_enable_chip(sc, 0);
+		RK_SPI_UNLOCK(sc);
+		return (err);
+	}
+
+	/* Transfer command then data bytes. */
+	err = 0;
+	if (cmd->tx_cmd_sz > 0)
+		err = rk_spi_xfer_buf(sc, cmd->rx_cmd, cmd->tx_cmd,
+		    cmd->tx_cmd_sz);
+	if (cmd->tx_data_sz > 0 && err == 0)
+		err = rk_spi_xfer_buf(sc, cmd->rx_data, cmd->tx_data,
+		    cmd->tx_data_sz);
+
+	rk_spi_set_cs(sc, cs, false);
+	rk_spi_enable_chip(sc, 0);
+	RK_SPI_UNLOCK(sc);
+
+	return (err);
+}
+
+static device_method_t rk_spi_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		rk_spi_probe),
+	DEVMETHOD(device_attach,	rk_spi_attach),
+	DEVMETHOD(device_detach,	rk_spi_detach),
+
+        /* spibus_if  */
+	DEVMETHOD(spibus_transfer,	rk_spi_transfer),
+
+        /* ofw_bus_if */
+	DEVMETHOD(ofw_bus_get_node,	rk_spi_get_node),
+
+	DEVMETHOD_END
+};
+
+static driver_t rk_spi_driver = {
+	"spi",
+	rk_spi_methods,
+	sizeof(struct rk_spi_softc),
+};
+
+static devclass_t rk_spi_devclass;
+
+DRIVER_MODULE(rk_spi, simplebus, rk_spi_driver, rk_spi_devclass, 0, 0);
+DRIVER_MODULE(ofw_spibus, rk_spi, ofw_spibus_driver, ofw_spibus_devclass, 0, 0);
+MODULE_DEPEND(rk_spi, ofw_spibus, 1, 1, 1);
+SIMPLEBUS_PNP_INFO(compat_data);

Copied and modified: stable/12/sys/arm64/rockchip/rk_typec_phy.c (from r354089, head/sys/arm64/rockchip/rk_typec_phy.c)
==============================================================================
--- head/sys/arm64/rockchip/rk_typec_phy.c	Fri Oct 25 18:10:02 2019	(r354089, copy source)
+++ stable/12/sys/arm64/rockchip/rk_typec_phy.c	Wed Mar  4 20:48:29 2020	(r358641)
@@ -191,7 +191,7 @@ rk_typec_phy_enable(struct phynode *phynode, bool enab
 	device_t dev;
 	intptr_t phy;
 	uint32_t reg;
-	int err;
+	int err, retry;
 
 	dev = phynode_get_device(phynode);
 	phy = phynode_get_id(phynode);
@@ -271,13 +271,13 @@ rk_typec_phy_enable(struct phynode *phynode, bool enab
 
 	hwreset_deassert(sc->rst_uphy);
 
-	for (int timeout = 10000; timeout > 0; timeout--) {
+	for (retry = 10000; retry > 0; retry--) {
 		reg = RK_TYPEC_PHY_READ(sc, PMA_CMN_CTRL1);
 		if (reg & PMA_CMN_CTRL1_READY)
 			break;
 		DELAY(10);
 	}
-	if (timeout == 0) {
+	if (retry == 0) {
 		device_printf(sc->dev, "Timeout waiting for PMA\n");
 		return (ENXIO);
 	}

Modified: stable/12/sys/conf/files.arm64
==============================================================================
--- stable/12/sys/conf/files.arm64	Wed Mar  4 20:43:29 2020	(r358640)
+++ stable/12/sys/conf/files.arm64	Wed Mar  4 20:48:29 2020	(r358641)
@@ -284,7 +284,9 @@ arm64/rockchip/rk805.c			optional fdt rk805 soc_rockch
 arm64/rockchip/rk_grf.c			optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399
 arm64/rockchip/rk_pinctrl.c		optional fdt rk_pinctrl soc_rockchip_rk3328 | fdt rk_pinctrl soc_rockchip_rk3399
 arm64/rockchip/rk_gpio.c		optional fdt rk_gpio soc_rockchip_rk3328 | fdt rk_gpio soc_rockchip_rk3399
+arm64/rockchip/rk_spi.c			optional fdt rk_spi
 arm64/rockchip/rk_usb2phy.c		optional fdt rk_usb2phy soc_rockchip_rk3328 | soc_rockchip_rk3399
+arm64/rockchip/rk_typec_phy.c		optional fdt rk_typec_phy soc_rockchip_rk3399
 arm64/rockchip/if_dwc_rk.c		optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399
 dev/dwc/if_dwc.c			optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399
 dev/dwc/if_dwc_if.m			optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399


More information about the svn-src-all mailing list