From 26ff3ccca7e4fb71ee8ebdae6f83a46376683449 Mon Sep 17 00:00:00 2001
From: Brijesh Jadav <brijesh.jadav@ti.com>
Date: Fri, 24 Jul 2020 16:11:33 +0530
Subject: [PATCH 1/1] Added support for flashing OSPI flash using CCS

Signed-off-by: Brijesh Jadav <brijesh.jadav@ti.com>
---
 .../utils/uniflash/target/build/uart_make.mk  |   5 +
 .../utils/uniflash/target/src/ccs_main.c      | 295 ++++++++++++++++++
 2 files changed, 300 insertions(+)
 create mode 100755 packages/ti/board/utils/uniflash/target/src/ccs_main.c

diff --git a/packages/ti/board/utils/uniflash/target/build/uart_make.mk b/packages/ti/board/utils/uniflash/target/build/uart_make.mk
index d521838..4d49144 100755
--- a/packages/ti/board/utils/uniflash/target/build/uart_make.mk
+++ b/packages/ti/board/utils/uniflash/target/build/uart_make.mk
@@ -45,6 +45,7 @@ TESTMODE ?= FUNCTIONAL_TEST
 MODENAME ?=
 BOARD_UTILS_CFLAGS ?=
 APP_NAME ?= board_utils_$(UNIFLASH)_flash_programmer
+USE_CCS ?= no
 
 BUILD_PROFILE_$(CORE) = $(PROFILE)
 
@@ -84,7 +85,11 @@ ifeq ($(BOARD), $(filter $(BOARD), j721e_evm))
 PACKAGE_SRCS_COMMON += ../../soc/k3
 endif
 
+ifeq ($(USE_CCS), no)
 SRCS_COMMON = uart_main.c xmodem.c soc.c
+else
+SRCS_COMMON = ccs_main.c soc.c
+endif
 
 ifeq ($(BOARD), $(filter $(BOARD), j721e_evm))
 SRCS_COMMON += ospi.c qspi.c hyperflash.c emmc.c diag_common_cfg.c
diff --git a/packages/ti/board/utils/uniflash/target/src/ccs_main.c b/packages/ti/board/utils/uniflash/target/src/ccs_main.c
new file mode 100755
index 0000000..56b69b0
--- /dev/null
+++ b/packages/ti/board/utils/uniflash/target/src/ccs_main.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 COPYRIGHT
+ * OWNER OR CONTRIBUTORS 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.
+ *
+ */
+
+/**
+ *  \file       uart_main.c
+ *
+ *  \brief      This file receives image with header from uart uniflash
+ *              and flash on device mentioned in the header.
+ *
+ */
+
+/* ========================================================================== */
+/*                             Include Files                                  */
+/* ========================================================================== */
+
+#include <xmodem.h>
+#include <ti/board/utils/uniflash/target/soc/soc.h>
+
+#include <ti/drv/uart/UART_stdio.h>
+#include <ti/drv/uart/soc/UART_soc.h>
+
+#ifdef SPI_FLASH
+#include <spi.h>
+#endif
+#ifdef QSPI_FLASH
+#include <qspi.h>
+#endif
+#ifdef OSPI_FLASH
+#include <ospi.h>
+#endif
+#ifdef EMMC_FLASH
+#include <emmc.h>
+#endif
+#ifdef HPF_FLASH
+#include <hyperflash.h>
+#endif
+
+#if defined(am65xx_evm) || defined(am65xx_idk) || defined(j721e_evm)
+#include <ti/osal/CacheP.h>
+#endif
+
+/* ========================================================================== */
+/*                            Defines                                         */
+/* ========================================================================== */
+
+#define MAX_CHAR                (60)
+#define FNAME_SZ                (512U)
+#define LOAD_ADDR               (0x90000000U)
+#define CHECK_ADDR              (0xA0000000U)
+#define FLASH_SIZE_ALIGN        (4096)
+
+/* ========================================================================== */
+/*                            Global Variables                                */
+/* ========================================================================== */
+
+extern uint32_t DELAY;
+extern uint8_t uart_inst;
+
+UFP_flashConfig UPF_flashFxnPtr[FLASH_DEVICE_MAX] = {
+    { NULL },                   // NAND
+    { NULL },                   // SPI
+    { NULL },                   // QSPI
+    { &UFP_ospiFxnTable },      // OSPI
+};
+
+#if defined(am65xx_evm) || defined(am65xx_idk) || defined(j721e_evm)
+#pragma DATA_SECTION(gSysFirmware, ".firmware")
+uint32_t gSysFirmware[1];
+#endif
+
+int main(void)
+{
+    int             retVal = 0;
+    int             i;
+    uint32_t        fileSize;
+    uint32_t        offset;
+    uint32_t        oper;
+    uint32_t        eraseLength;
+    uint32_t        input;
+    FILE           *fPtr = NULL;
+    uint8_t        *srcAddr = (uint8_t *)LOAD_ADDR;
+    uint8_t        *checkAddr = (uint8_t *)CHECK_ADDR;
+    uint32_t        devType = 3;
+    char      fileName[FNAME_SZ];
+
+    if (UFP_socInit(NULL))
+    {
+        return -1;
+    }
+
+    do
+    {
+        /* Reset Variables */
+        srcAddr = (uint8_t *)LOAD_ADDR;
+        checkAddr = (uint8_t *)CHECK_ADDR;
+        offset = 0;
+        eraseLength = 0;
+
+        /* Select the input option */
+        do
+        {
+            printf (" 0: Erase Flash\n");
+            printf (" 1: Write to Flash\n");
+            printf (" 2: exit\n");
+            scanf("%d", &oper);
+
+            if (oper < 3)
+            {
+                break;
+            }
+        } while (1);
+
+        /* Exit for option 2 */
+        if (2 == oper)
+        {
+            break;
+        }
+
+        if (!oper)
+        {
+            /* Select Offset and size for erase operation */
+            printf (" Enter the Offset in bytes (HEX): \n");
+            scanf("%x", &offset);
+            printf (" Enter the erase size in bytes: \n");
+            scanf("%d", &eraseLength);
+        }
+        else
+        {
+            /* Select Input file and read the file */
+            memset((void *) fileName, (int32_t) 0U, sizeof (fileName));
+            printf (" Enter File Name with Path to flash \n");
+            scanf("%511s", fileName);
+
+            if ((fileName[0] == (char) '0') && (((uint32_t)fileName[1]) == 0x0))
+            {
+                /* Set option variable to '0' to erase without flashing */
+                break;
+            }
+
+            for (i = 0; i < (sizeof (fileName) - 1U); i++)
+            {
+                if (fileName[i] == (char) '\\')
+                {
+                    if (i != sizeof (fileName))
+                    {
+                        if (fileName[i + 1U] != (char) '\\')
+                        {
+                            fileName[i] = (char) '/';
+                        }
+                    }
+                }
+            }
+
+            printf (" Enter the Offset in bytes (HEX): \n");
+            scanf("%x", &offset);
+
+            fPtr = fopen(fileName, "rb");
+            if (fPtr == NULL)
+            {
+                printf(" ERROR: File %s\n", fileName);
+                break;
+            }
+            else
+            {
+                /* Read file size */
+                fseek(fPtr, 0, SEEK_END);
+                fileSize = (uint32_t) ftell(fPtr);
+                if (fileSize == 0U)
+                {
+                    printf(" ERROR: File read failed.. Closing program.\n");
+                    fclose(fPtr);
+                    break;
+                }
+                fileSize = (fileSize + (FLASH_SIZE_ALIGN - 1)) & (~(FLASH_SIZE_ALIGN - 1));
+            }
+
+            if (0 == retVal)
+            {
+                memset((void *) srcAddr, (int32_t) 0U, fileSize);
+
+                printf(" Use below command in CCS scripting console...\n");
+                printf(" loadRaw(0x%.8x, 0, \"%s\", 32, false);\n",
+                       srcAddr,
+                       fileName);
+                printf(
+                    " Kindly use '/' (forward slash) in the file path.\n");
+                printf(
+                    " Enter any alpha-numeric key once loadraw is complete...\n");
+                scanf("%u", &input);
+            }
+        }
+
+        if (0 == retVal)
+        {
+            if (NULL == UPF_flashFxnPtr[devType].UPF_fxnTablePtr->UFP_flashInit)
+            {
+                printf (" FlashInit Null\n");
+                break;
+            }
+            else
+            {
+                retVal = UPF_flashFxnPtr[devType].UPF_fxnTablePtr->UFP_flashInit();
+                if (retVal != 0)
+                {
+                    printf (" ERROR: FlashInit Failed\n");
+                    break;
+                }
+            }
+
+            if (!oper)
+            {
+                retVal = UPF_flashFxnPtr[devType].UPF_fxnTablePtr->
+                    UFP_flashErase(offset, eraseLength);
+                if (retVal != 0)
+                {
+                    printf (" Unable to Erase flash\n");
+                }
+            }
+            else
+            {
+                for (i = 0; i < fileSize/FLASH_SIZE_ALIGN; i ++)
+                {
+                    retVal = UPF_flashFxnPtr[devType].UPF_fxnTablePtr->
+                        UFP_flashProgram(srcAddr, checkAddr, offset, FLASH_SIZE_ALIGN);
+                    if (retVal != 0)
+                    {
+                        printf (" Flash Write failed \n");
+                        break;
+                    }
+                    srcAddr += FLASH_SIZE_ALIGN;
+                    checkAddr += FLASH_SIZE_ALIGN;
+                    offset += FLASH_SIZE_ALIGN;
+                }
+
+                memset((void *) LOAD_ADDR, (int32_t) 0U, fileSize);
+            }
+
+            UPF_flashFxnPtr[devType].UPF_fxnTablePtr->UFP_flashClose();
+        }
+
+    } while (1);
+
+    return 0;
+}
+
+int8_t UFP_uartConfig(uint32_t baudrate)
+{
+    /* dummy function */
+
+    return 0;
+}
+
+/**
+ *  \brief      This function generates delay in msec.
+ *
+ *  \param      delay_val   [IN]    delay value
+ *
+ */
+void delay(uint16_t delay_val)
+{
+    uint32_t delayVal;
+    delayVal = delay_val * 1000;
+    while(delayVal--);
+}
+
-- 
2.17.1

