/* * Copyright (c) 2016 Open-RnD Sp. z o.o. * Copyright (c) 2016 Linaro Limited. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief System/hardware module for ATJ215X processor */ #include #include #include #include "soc.h" #include //#include static void jtag_config(unsigned int group_id) { printk("jtag switch to group=%d\n", group_id); if (group_id < 3) sys_write32((sys_read32(JTAG_CTL) & ~(3 << 0)) | (group_id << 0) | (1 << 4), JTAG_CTL); } void jtag_set(void) { jtag_config(0); } /** * \brief clear watchdog */ void soc_watchdog_clear(void) { sys_set_bit(WD_CTL, 0); } static void wd_check_wdreset_cnt(void) { uint32_t reset_cnt; soc_watchdog_clear(); soc_pstore_get(SOC_PSTORE_TAG_WD_RESET_CNT, &reset_cnt); printk("wd cnt=%d, WD_CTL=0x%x\n", reset_cnt, sys_read32(WD_CTL)); if(reset_cnt > 10){ printk("reboot ota\n"); soc_pstore_set(SOC_PSTORE_TAG_WD_RESET_CNT, 0); sys_pm_reboot(REBOOT_TYPE_GOTO_OTA); }else{ reset_cnt++; soc_pstore_set(SOC_PSTORE_TAG_WD_RESET_CNT, reset_cnt); } } /** * \brief if boot to main clear wd reset cnt */ void wd_clear_wdreset_cnt(void) { soc_pstore_set(SOC_PSTORE_TAG_WD_RESET_CNT, 0); } __sleepfunc int soc_dvfs_opt(void) { return (sys_read32(UID1) >> 17) & 0x7; } uint8_t ipmsg_btc_get_ic_pkt(void) { uint32_t val; val = sys_read32(UID1); return (uint8_t)((val >> 24) & 0xF); /* bit24~27: IC Package */ } #if 0 static void cpu_init(void) { int i; unsigned int val; printk("rc192 cal\n"); sys_write32(0x80011481, RC192M_CTL); soc_udelay(20); sys_write32(0x8001148d, RC192M_CTL); soc_udelay(200); while(1){ if(sys_read32(RC192M_CTL)& (1<<24)){ for(i = 0; i < 3; i++){ // 3 cal done is ok soc_udelay(20); if(!(sys_read32(RC192M_CTL)& (1<<24))) break; } if(i == 3) break; } } val = (sys_read32(RC192M_CTL) & (0x7f<<25)) >> 25; if(val) val -= 1; sys_write32(0x80011001 | (val<<4) , RC192M_CTL); soc_udelay(200); sys_write32(0x215, CMU_SYSCLK);// CPU rcM256/2 =128, ahb div 1 } #endif __sleepfunc static void leopard_set_hosc_ctrl() { /* IO_WRITE(HOSC_CTL, (0x601f1b6 | (CAP<<17))); 如果是首次配置(HOSC_CTL[25]: 0->1)需要将CPUCLK切换到RC4M,等待HOSC_CTL[28]为1后再将CPUCLK切回HOSC/COREPLL */ uint32_t val; /* switch cpuclk src to 4MRC */ val = sys_read32(CMU_SYSCLK); sys_write32(val & ~0x7, CMU_SYSCLK); /* update HOSC_CTL & wait HOSC_READY */ sys_write32(0x600f7f6 | (sys_read32(HOSC_CTL) & HOSC_CTL_HOSC_CAP_MASK), HOSC_CTL); while(!(sys_read32(HOSC_CTL) & (1<< HOSC_CTL_HOSC_READY))); /* backup cpuclk src to COREPLL */ sys_write32(val, CMU_SYSCLK); } /** * @brief Perform basic hardware initialization at boot. * * This needs to be run from the very beginning. * So the init priority has to be 0 (zero). * * @return 0 */ static int leopard_init(const struct device *arg) { uint32_t key; uint32_t val; ARG_UNUSED(arg); soc_udelay(50); leopard_set_hosc_ctrl(); soc_udelay(10); key = irq_lock(); /* Install default handler that simply resets the CPU * if configured in the kernel, NOP otherwise */ NMI_INIT(); irq_unlock(key); soc_powergate_init(); sys_write32(0x10e, CMU_GPUCLK);//COREPLL/1.5 acts_clock_peripheral_enable(CLOCK_ID_GPU); //for the gpu reset, because the gpu is in an unstable state soc_udelay(1); acts_reset_peripheral_deassert(RESET_ID_GPU); soc_udelay(1); acts_reset_peripheral_assert(RESET_ID_GPU);// soc_udelay(2); acts_clock_peripheral_disable(CLOCK_ID_GPU);// /* disable gpu power gating */ //sys_write32(sys_read32(PWRGATE_DIG) & ~(0x1 << 25), PWRGATE_DIG); if(soc_powergate_is_poweron(POWERGATE_GPU_PG_DEV)) soc_powergate_set(POWERGATE_GPU_PG_DEV, false); //cpu_init(); wd_check_wdreset_cnt(); /* Update CMSIS SystemCoreClock variable (HCLK) */ /* At reset, system core clock is set to 16 MHz from HSI */ //SystemCoreClock = 16000000; //while(!arg); //sys_write32(0x0, WIO0_CTL); //default set wio0 to gpio func /*for lowpower*/ //sys_write32(0x30F, SPI1_CLKGATING); /* init ppi */ ppi_init(); /* Initialize SDMA */ acts_reset_peripheral_assert(RESET_ID_SDMA); acts_clock_peripheral_enable(CLOCK_ID_SDMA); acts_reset_peripheral_deassert(RESET_ID_SDMA); /* Enable SDMA, DE access SPI0 NOR and SPI1 PSRAM, and GPU accessing SPI1 PSRAM */ //sys_write32(sys_read32(SPICACHE_CTL) | BIT(10) | BIT(11), SPICACHE_CTL); sys_write32((sys_read32(SPICACHE_CTL) & ~(0x3 << 5)) | (0x1 << 5) | BIT(10) | BIT(11), SPICACHE_CTL); if (soc_dvfs_opt()) { sys_write32((sys_read32(SPI1_DELAYCHAIN) & ~(0x3f << 8)) \ | (SPI1_DELAYCHAIN_CLKOUT << 8), SPI1_DELAYCHAIN); sys_write32(sys_read32(SPI1_CACHE_CTL) | BIT(8) | BIT(10) | BIT(11) | BIT(14) | BIT(15), SPI1_CACHE_CTL); } else { sys_write32(sys_read32(SPI1_CACHE_CTL) | BIT(8) | BIT(10) | BIT(11) | BIT(14) /*| BIT(15)*/, SPI1_CACHE_CTL); } sys_write32(BIT(24) | (0<<4) | (0xa<<8) | (0x1<<0), SPI1_GPU_CTL); /* Share RAM clock, select HOSC(32MHZ)*/ val = sys_read32(CMU_MEMCLKSRC0); val = (val & ~(7 << 25)) | (1 << 25); sys_write32(val, CMU_MEMCLKSRC0); val = sys_read32(CMU_MEMCLKEN0); val |= (1 << 25); sys_write32(val, CMU_MEMCLKEN0); //val = sys_read32(VOUT_CTL1_S1M) ; //val = (val & ~(0xFff)) | 0xedd; // vdd set 1.2 //sys_write32(val, VOUT_CTL1_S1M); //sys_write32(0x12, CMU_SYSCLK);// cpu 200 return 0; } SYS_INIT(leopard_init, PRE_KERNEL_1, 0); /*if CONFIG_WDOG_ACTS enable , wd driver call wd_clear_wdreset_cnt */ #ifndef CONFIG_WDOG_ACTS /** * @brief Perform basic hardware initialization at boot. * * before boot to main clear wd reset cnt * @return 0 */ static int wd_reset_cnt_init(const struct device *arg) { wd_clear_wdreset_cnt(); sys_write32(0, WD_CTL); /*disable watch dog*/ return 0; } SYS_INIT(wd_reset_cnt_init, APPLICATION, 91); #endif