Blob Blame History Raw
From b0b1b81a11f8bae8ab9e8edd87ac3f4f7949d03b Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <phcoder@gmail.com>
Date: Tue, 9 May 2017 08:42:14 +0200
Subject: [PATCH 032/227] rk3288_spi: Add SPI driver

---
 grub-core/Makefile.core.def        |   1 +
 grub-core/bus/spi/rk3288_spi.c     | 103 +++++++++++++++++++++++++++++++++++++
 grub-core/kern/arm/coreboot/init.c |   2 +
 include/grub/arm/coreboot/kernel.h |   4 +-
 4 files changed, 108 insertions(+), 2 deletions(-)
 create mode 100644 grub-core/bus/spi/rk3288_spi.c

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