bc092b9
From b0b1b81a11f8bae8ab9e8edd87ac3f4f7949d03b Mon Sep 17 00:00:00 2001
bc092b9
From: Vladimir Serbinenko <phcoder@gmail.com>
bc092b9
Date: Tue, 9 May 2017 08:42:14 +0200
78e1a10
Subject: [PATCH 032/216] rk3288_spi: Add SPI driver
bc092b9
bc092b9
---
bc092b9
 grub-core/Makefile.core.def        |   1 +
bc092b9
 grub-core/bus/spi/rk3288_spi.c     | 103 +++++++++++++++++++++++++++++++++++++
bc092b9
 grub-core/kern/arm/coreboot/init.c |   2 +
bc092b9
 include/grub/arm/coreboot/kernel.h |   4 +-
bc092b9
 4 files changed, 108 insertions(+), 2 deletions(-)
bc092b9
 create mode 100644 grub-core/bus/spi/rk3288_spi.c
bc092b9
bc092b9
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
ec4acbb
index 5ce506597a6..d2239f1718d 100644
bc092b9
--- a/grub-core/Makefile.core.def
bc092b9
+++ b/grub-core/Makefile.core.def
bc092b9
@@ -162,6 +162,7 @@ kernel = {
bc092b9
   arm_coreboot = bus/fdt.c;
bc092b9
   arm_coreboot = term/ps2.c;
bc092b9
   arm_coreboot = term/arm/pl050.c;
bc092b9
+  arm_coreboot = bus/spi/rk3288_spi.c;
bc092b9
   arm_coreboot = commands/keylayouts.c;
bc092b9
   arm_coreboot = kern/arm/coreboot/dma.c;
bc092b9
 
bc092b9
diff --git a/grub-core/bus/spi/rk3288_spi.c b/grub-core/bus/spi/rk3288_spi.c
bc092b9
new file mode 100644
ec4acbb
index 00000000000..aacb79ffef1
bc092b9
--- /dev/null
bc092b9
+++ b/grub-core/bus/spi/rk3288_spi.c
bc092b9
@@ -0,0 +1,103 @@
bc092b9
+/*
bc092b9
+ *  GRUB  --  GRand Unified Bootloader
bc092b9
+ *
bc092b9
+ *  Copyright (C) 2012  Google Inc.
bc092b9
+ *  Copyright (C) 2016  Free Software Foundation, Inc.
bc092b9
+ *
bc092b9
+ *  This is based on depthcharge code.
bc092b9
+ *
bc092b9
+ *  GRUB is free software: you can redistribute it and/or modify
bc092b9
+ *  it under the terms of the GNU General Public License as published by
bc092b9
+ *  the Free Software Foundation, either version 3 of the License, or
bc092b9
+ *  (at your option) any later version.
bc092b9
+ *
bc092b9
+ *  GRUB is distributed in the hope that it will be useful,
bc092b9
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
bc092b9
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
bc092b9
+ *  GNU General Public License for more details.
bc092b9
+ *
bc092b9
+ *  You should have received a copy of the GNU General Public License
bc092b9
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
bc092b9
+ */
bc092b9
+
bc092b9
+#include <grub/mm.h>
bc092b9
+#include <grub/time.h>
bc092b9
+#include <grub/misc.h>
bc092b9
+#include <grub/fdtbus.h>
bc092b9
+#include <grub/machine/kernel.h>
bc092b9
+
bc092b9
+static grub_err_t
bc092b9
+spi_send (const struct grub_fdtbus_dev *dev, const void *data, grub_size_t sz)
bc092b9
+{
bc092b9
+  const grub_uint8_t *ptr = data, *end = ptr + sz;
bc092b9
+  volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
bc092b9
+  spi[2] = 0;
bc092b9
+  spi[1] = sz - 1;
bc092b9
+  spi[0] = ((1 << 18) | spi[0]) & ~(1 << 19);
bc092b9
+  spi[2] = 1;
bc092b9
+  while (ptr < end)
bc092b9
+    {
bc092b9
+      while (spi[9] & 2);
bc092b9
+      spi[256] = *ptr++;
bc092b9
+    }
bc092b9
+  while (spi[9] & 1);
bc092b9
+  return GRUB_ERR_NONE;
bc092b9
+}
bc092b9
+
bc092b9
+static grub_err_t
bc092b9
+spi_receive (const struct grub_fdtbus_dev *dev, void *data, grub_size_t sz)
bc092b9
+{
bc092b9
+  grub_uint8_t *ptr = data, *end = ptr + sz;
bc092b9
+  volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
bc092b9
+  spi[2] = 0;
bc092b9
+  spi[1] = sz - 1;
bc092b9
+  spi[0] = ((1 << 19) | spi[0]) & ~(1 << 18);
bc092b9
+  spi[2] = 1;
bc092b9
+  while (ptr < end)
bc092b9
+    {
bc092b9
+      while (spi[9] & 8);
bc092b9
+      *ptr++ = spi[512];
bc092b9
+    }
bc092b9
+  while (spi[9] & 1);
bc092b9
+  return GRUB_ERR_NONE;
bc092b9
+}
bc092b9
+
bc092b9
+static grub_err_t
bc092b9
+spi_start (const struct grub_fdtbus_dev *dev)
bc092b9
+{
bc092b9
+  volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
bc092b9
+  spi[3] = 1;
bc092b9
+  return GRUB_ERR_NONE;
bc092b9
+}
bc092b9
+
bc092b9
+static void
bc092b9
+spi_stop (const struct grub_fdtbus_dev *dev)
bc092b9
+{
bc092b9
+  volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
bc092b9
+  spi[3] = 0;
bc092b9
+}
bc092b9
+
bc092b9
+static grub_err_t
bc092b9
+spi_attach(const struct grub_fdtbus_dev *dev)
bc092b9
+{
bc092b9
+  if (!grub_fdtbus_is_mapping_valid (grub_fdtbus_map_reg (dev, 0, 0)))
bc092b9
+    return GRUB_ERR_IO;
bc092b9
+
bc092b9
+  return GRUB_ERR_NONE;
bc092b9
+}
bc092b9
+
bc092b9
+static struct grub_fdtbus_driver spi =
bc092b9
+{
bc092b9
+  .compatible = "rockchip,rk3288-spi",
bc092b9
+  .attach = spi_attach,
bc092b9
+  .send = spi_send,
bc092b9
+  .receive = spi_receive,
bc092b9
+  .start = spi_start,
bc092b9
+  .stop = spi_stop,
bc092b9
+};
bc092b9
+
bc092b9
+void
bc092b9
+grub_rk3288_spi_init (void)
bc092b9
+{
bc092b9
+  grub_fdtbus_register (&spi;;
bc092b9
+}
bc092b9
diff --git a/grub-core/kern/arm/coreboot/init.c b/grub-core/kern/arm/coreboot/init.c
ec4acbb
index a06ccb72f42..0126ff6381a 100644
bc092b9
--- a/grub-core/kern/arm/coreboot/init.c
bc092b9
+++ b/grub-core/kern/arm/coreboot/init.c
bc092b9
@@ -132,6 +132,8 @@ grub_machine_init (void)
bc092b9
     grub_fatal ("No DTB found");
bc092b9
   grub_fdtbus_init (dtb, dtb_size);
bc092b9
 
bc092b9
+  grub_rk3288_spi_init ();
bc092b9
+
bc092b9
   grub_machine_timer_init ();
bc092b9
   grub_pl050_init ();
bc092b9
 }
bc092b9
diff --git a/include/grub/arm/coreboot/kernel.h b/include/grub/arm/coreboot/kernel.h
ec4acbb
index 09cd7fe328c..26950534270 100644
bc092b9
--- a/include/grub/arm/coreboot/kernel.h
bc092b9
+++ b/include/grub/arm/coreboot/kernel.h
bc092b9
@@ -34,8 +34,8 @@ struct grub_fdt_board
bc092b9
 extern struct grub_fdt_board grub_fdt_boards[];
bc092b9
 void grub_machine_timer_init (void);
bc092b9
 void grub_pl050_init (void);
bc092b9
-void
bc092b9
-grub_cros_init (void);
bc092b9
+void grub_cros_init (void);
bc092b9
+void grub_rk3288_spi_init (void);
bc092b9
 extern grub_addr_t EXPORT_VAR (start_of_ram);
bc092b9
 #endif /* ! ASM_FILE */
bc092b9
 
bc092b9
-- 
ec4acbb
2.15.0
bc092b9