[gauss] Gauss board driver for Amlogic RAW_NAND.

Change-Id: I0d7b657e184c43aa4b4d61bc7c1be0cb0f02dc54
diff --git a/system/dev/board/gauss/gauss-rawnand.c b/system/dev/board/gauss/gauss-rawnand.c
new file mode 100644
index 0000000..87ab421
--- /dev/null
+++ b/system/dev/board/gauss/gauss-rawnand.c
@@ -0,0 +1,92 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <ddk/debug.h>
+#include <ddk/device.h>
+#include <ddk/io-buffer.h>
+#include <ddk/protocol/gpio.h>
+#include <ddk/protocol/platform-bus.h>
+#include <ddk/protocol/platform-defs.h>
+#include <hw/reg.h>
+#include <soc/aml-a113/a113-hw.h>
+#include <unistd.h>
+
+#include "gauss.h"
+#include "gauss-hw.h"
+
+static const pbus_mmio_t raw_nand_mmios[] = {
+    {   /* nandreg : Registers for NAND controller */
+        .base = GAUSS_RAW_NAND_REG,
+        .length = 0x2000,
+    },
+    {   /* clockreg : Clock Register for NAND controller */
+        /*
+         * From the Linux devicetree. This is the base SD_EMMC_CLOCK
+         * register (for port C)
+         */
+        .base = GAUSS_RAW_NAND_CLKREG,
+        .length = 0x4,  /* Just 4 bytes */
+    },
+};
+
+static const pbus_irq_t raw_nand_irqs[] = {
+    {
+        .irq = GAUSS_RAW_NAND_IRQ,
+    },
+};
+
+static const pbus_bti_t raw_nand_btis[] = {
+    {
+        .iommu_index = 0,
+        .bti_id = BTI_AML_RAW_NAND,
+    },
+};
+
+static const pbus_dev_t raw_nand_dev = {
+    .name = "aml_raw_nand",
+    .vid = PDEV_VID_AMLOGIC,
+    .pid = PDEV_PID_GENERIC,
+    .did = PDEV_DID_AMLOGIC_RAW_NAND,
+    .mmios = raw_nand_mmios,
+    .mmio_count = countof(raw_nand_mmios),
+    .irqs = raw_nand_irqs,
+    .irq_count = countof(raw_nand_irqs),
+    .btis = raw_nand_btis,
+    .bti_count = countof(raw_nand_btis),
+};
+
+zx_status_t gauss_raw_nand_init(gauss_bus_t* bus) {
+    zx_status_t status;
+
+    // set alternate functions to enable raw_nand
+    status = gpio_set_alt_function(&bus->gpio, A113_GPIOBOOT(8), 2);
+    if (status != ZX_OK)
+        return status;
+    status = gpio_set_alt_function(&bus->gpio, A113_GPIOBOOT(9), 2);
+    if (status != ZX_OK)
+        return status;
+    status = gpio_set_alt_function(&bus->gpio, A113_GPIOBOOT(10), 2);
+    if (status != ZX_OK)
+        return status;
+    status = gpio_set_alt_function(&bus->gpio, A113_GPIOBOOT(11), 2);
+    if (status != ZX_OK)
+        return status;
+    status = gpio_set_alt_function(&bus->gpio, A113_GPIOBOOT(12), 2);
+    if (status != ZX_OK)
+        return status;
+    status = gpio_set_alt_function(&bus->gpio, A113_GPIOBOOT(13), 2);
+    if (status != ZX_OK)
+        return status;
+
+    status = pbus_device_add(&bus->pbus, &raw_nand_dev, PDEV_ADD_PBUS_DEVHOST);
+    if (status != ZX_OK) {
+        zxlogf(ERROR, "gauss_raw_nand_init: pbus_device_add raw_nand failed: %d\n",
+               status);
+        return status;
+    }
+
+    return ZX_OK;
+}
+
+
diff --git a/system/dev/board/gauss/gauss.c b/system/dev/board/gauss/gauss.c
index 6fcdc7a..215e525 100644
--- a/system/dev/board/gauss/gauss.c
+++ b/system/dev/board/gauss/gauss.c
@@ -193,6 +193,11 @@
     }
 #endif
 
+    if ((status = gauss_raw_nand_init(bus)) != ZX_OK) {
+        zxlogf(ERROR, "gauss_raw_nand_init failed: %d\n", status);
+        goto fail;
+    }
+
     if ((status = pbus_device_add(&bus->pbus, &led_dev, 0)) != ZX_OK) {
         zxlogf(ERROR, "a113_i2c_init could not add i2c_led_dev: %d\n", status);
         goto fail;
diff --git a/system/dev/board/gauss/gauss.h b/system/dev/board/gauss/gauss.h
index 2e093a2..bd63104 100644
--- a/system/dev/board/gauss/gauss.h
+++ b/system/dev/board/gauss/gauss.h
@@ -28,6 +28,7 @@
     BTI_AUDIO_IN,
     BTI_AUDIO_OUT,
     BTI_USB_XHCI,
+    BTI_AML_RAW_NAND,
 };
 
 typedef struct {
@@ -63,3 +64,6 @@
 
 // gauss-pcie.c
 zx_status_t gauss_pcie_init(gauss_bus_t* bus);
+
+// gauss-raw_nand.c
+zx_status_t gauss_raw_nand_init(gauss_bus_t* bus);
diff --git a/system/dev/board/gauss/rules.mk b/system/dev/board/gauss/rules.mk
index f367d42..e6a1ac2 100644
--- a/system/dev/board/gauss/rules.mk
+++ b/system/dev/board/gauss/rules.mk
@@ -16,6 +16,7 @@
     $(LOCAL_DIR)/gauss-i2c.c \
     $(LOCAL_DIR)/gauss-pcie.c \
     $(LOCAL_DIR)/gauss-usb.c \
+    $(LOCAL_DIR)/gauss-rawnand.c \
 
 MODULE_STATIC_LIBS := \
     system/dev/lib/amlogic \
diff --git a/system/dev/lib/amlogic/include/soc/aml-a113/a113-hw.h b/system/dev/lib/amlogic/include/soc/aml-a113/a113-hw.h
index 9fa2997..5a90726 100644
--- a/system/dev/lib/amlogic/include/soc/aml-a113/a113-hw.h
+++ b/system/dev/lib/amlogic/include/soc/aml-a113/a113-hw.h
@@ -19,3 +19,7 @@
 // Clock Control
 #define AXG_HIU_BASE_PHYS 0xff63c000
 
+// RAW_NAND MMIO and IRQ
+#define GAUSS_RAW_NAND_REG   0xffe07800
+#define GAUSS_RAW_NAND_CLKREG   0xffe07000
+#define GAUSS_RAW_NAND_IRQ   66