/*********************************************************************
*               (c) SEGGER Microcontroller GmbH & Co. KG             *
*                        The Embedded Experts                        *
*                           www.segger.com                           *
**********************************************************************

-------------------------- END-OF-HEADER -----------------------------
*/

/*********************************************************************
*
*       ResetTarget
*/
void ResetTarget(void) {
  //
  // This device requires a special reset as default reset does not work for this device.
  // TBD
  //
}

/*********************************************************************
*
*       InitTarget
*/
void InitTarget(void) {
  int v;
  int Ctrl;
  int CSGPR_ADDR;
  int DP_REG_CTRL_STAT;
  int DP_REG_SELECT;
  int APBAP_REG_CTRL;
  int APBAP_REG_ADDR;
  int APBAP_REG_DATA;

  CSGPR_ADDR         = 0x80070000;
  DP_REG_CTRL_STAT   = 1;
  DP_REG_SELECT      = 2;
  APBAP_REG_CTRL     = 0;
  APBAP_REG_ADDR     = 1;
  APBAP_REG_DATA     = 3;

  Report("***************************************************");
  Report("J-Link script: iMX8QX Cortex-M4 core0 J-Link script");
  Report("***************************************************");
  JLINK_CORESIGHT_Configure("IRPre=0;DRPre=0;IRPost=0;DRPost=0;IRLenDevice=4");
  CPU = CORTEX_M4;                                                              // Pre-select that we have a Cortex-M4 connected
  JTAG_AllowTAPReset = 0;                                                       // J-Link is allowed to use a TAP reset for JTAG-chain auto-detection

  //
  // Power-up complete DAP
  //
  Ctrl = 0
       | (1 << 30)    // System power-up
       | (1 << 28)    // Debug popwer-up
       | (1 << 5)     // Clear STICKYERR
       ;
  JLINK_CORESIGHT_WriteDP(DP_REG_CTRL_STAT, Ctrl);

  //
  // Select AHB-AP and configure it
  //
  JLINK_CORESIGHT_WriteDP(DP_REG_SELECT, (0 << 4) | (4 << 24));
  JLINK_CORESIGHT_WriteAP(APBAP_REG_CTRL, (2 << 0) | (1 << 31));

  // Kick off M4_0
  JLINK_CORESIGHT_WriteAP(APBAP_REG_ADDR, CSGPR_ADDR);
  v = JLINK_CORESIGHT_ReadAP(APBAP_REG_DATA);
  v |= 1 << 6;
  JLINK_CORESIGHT_WriteAP(APBAP_REG_ADDR, CSGPR_ADDR);
  JLINK_CORESIGHT_WriteAP(APBAP_REG_DATA, v);

  // Wait 100ms to make sure M4_0 wakeup
  SYS_Sleep(100);

  //
  // Manually configure which APs are present on the CoreSight device
  //
  JTAG_SetDeviceId(0, 0x5BA00477);  // 4-bits IRLen
  CORESIGHT_AddAP(0, CORESIGHT_AHB_AP);  // AXI-AP
  CORESIGHT_AddAP(1, CORESIGHT_AHB_AP);  // SCU-AP
  CORESIGHT_AddAP(2, CORESIGHT_AHB_AP);  // CM4-0-AP
  CORESIGHT_AddAP(3, CORESIGHT_AHB_AP);  // CM0+
  CORESIGHT_AddAP(4, CORESIGHT_APB_AP);  // APB-AP for CA53

  CORESIGHT_IndexAHBAPToUse = 2;
}

/*********************************************************************
*
*       SetupTarget
*/
void SetupTarget(void)
{
  // Configure LMEM Parity/ECC Control Register
  //
  // Note: ECC Multi-bit IRQ should be disabled
  //       prior to list/dump of locations that
  //       have not been written to avoid vectoring
  //       to the NMI
  //
  // 31:22 RESERVED
  // 21    Enable Cache Parity IRQ
  // 20    Enable Cache Parity Report
  // 19:17 RESERVED
  // 16    Enable RAM Parity Reporting
  // 15:10 RESERVED
  // 9     Enable RAM ECC 1-bit IRQ
  // 8     Enable RAM ECC 1-bit Report
  // 7:2   RESERVED
  // 1     Enable RAM ECC Multi-bit IRQ
  // 0     Enable RAM ECC Multi-bit
  JLINK_MEM_WriteU32(0xE0080480, 0x0);
}
