<commit_before>/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* System module for Chrome EC : NPCX hardware specific implementation */

#include "clock.h"
#include "common.h"
#include "console.h"
#include "cpu.h"
#include "host_command.h"
#include "registers.h"
#include "system.h"
#include "hooks.h"
#include "task.h"
#include "timer.h"
#include "util.h"
#include "gpio.h"
#include "hwtimer_chip.h"
#include "system_chip.h"
#include "clock_chip.h"
#include "rom_chip.h"

/* Flags for BBRM_DATA_INDEX_WAKE */
#define HIBERNATE_WAKE_MTC        (1 << 0)  /* MTC alarm */
#define HIBERNATE_WAKE_PIN        (1 << 1)  /* Wake pin */

/* equivalent to 250us according to 48MHz core clock */
#define MTC_TTC_LOAD_DELAY 1500
#define MTC_ALARM_MASK     ((1 << 25) - 1)
#define MTC_WUI_GROUP      MIWU_GROUP_4
#define MTC_WUI_MASK       MASK_PIN7

/* ROM address of chip revision */
#define CHIP_REV_ADDR 0x00007FFC

/* Console output macros */
#define CPUTS(outstr) cputs(CC_SYSTEM, outstr)
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)

/* Begin address for the .lpram section; defined in linker script */
uintptr_t __lpram_fw_start = CONFIG_LPRAM_BASE;

/*****************************************************************************/
/* Internal functions */

void system_watchdog_reset(void)
{
	/* Unlock & stop watchdog registers */
	NPCX_WDSDM = 0x87;
	NPCX_WDSDM = 0x61;
	NPCX_WDSDM = 0x63;

	/* Reset TWCFG */
	NPCX_TWCFG = 0;
	/* Select T0IN clock as watchdog prescaler clock */
	SET_BIT(NPCX_TWCFG, NPCX_TWCFG_WDCT0I);

	/* Clear watchdog reset status initially*/
	SET_BIT(NPCX_T0CSR, NPCX_T0CSR_WDRST_STS);

	/* Keep prescaler ratio timer0 clock to 1:1 */
	NPCX_TWCP = 0x00;

	/* Set internal counter and prescaler */
	NPCX_TWDT0 = 0x00;
	NPCX_WDCNT = 0x01;

	/* Disable interrupt */
	interrupt_disable();
	/* Reload and restart Timer 0*/
	SET_BIT(NPCX_T0CSR, NPCX_T0CSR_RST);
	/* Wait for timer is loaded and restart */
	while (IS_BIT_SET(NPCX_T0CSR, NPCX_T0CSR_RST))
		;
	/* Enable interrupt */
	interrupt_enable();
}

/**
 * Read battery-backed ram (BBRAM) at specified index.
 *
 * @return The value of the register or 0 if invalid index.
 */
static uint32_t bbram_data_read(enum bbram_data_index index)
{
	uint32_t value = 0;
	/* Check index */
	if (index < 0 || index >= NPCX_BBRAM_SIZE)
		return 0;

	/* BBRAM is valid */
	if (IS_BIT_SET(NPCX_BKUP_STS, NPCX_BKUP_STS_IBBR))
		return 0;

	/* Read BBRAM */
	value += NPCX_BBRAM(index + 3);
	value = value << 8;
	value += NPCX_BBRAM(index + 2);
	value = value << 8;
	value += NPCX_BBRAM(index + 1);
	value = value << 8;
	value += NPCX_BBRAM(index);

	return value;
}

/**
 * Write battery-backed ram (BBRAM) at specified index.
 *
 * @return nonzero if error.
 */
static int bbram_data_write(enum bbram_data_index index, uint32_t value)
{
	/* Check index */
	if (index < 0 || index >= NPCX_BBRAM_SIZE)
		return EC_ERROR_INVAL;

	/* BBRAM is valid */
	if (IS_BIT_SET(NPCX_BKUP_STS, NPCX_BKUP_STS_IBBR))
		return EC_ERROR_INVAL;

	/* Write BBRAM */
	NPCX_BBRAM(index)     = value & 0xFF;
	NPCX_BBRAM(index + 1) = (value >> 8)  & 0xFF;
	NPCX_BBRAM(index + 2) = (value >> 16) & 0xFF;
	NPCX_BBRAM(index + 3) = (value >> 24) & 0xFF;

	/* Wait for write-complete */
	return EC_SUCCESS;
}

/* MTC functions */
uint32_t system_get_rtc_sec(void)
{
	/* Get MTC counter unit:seconds */
	uint32_t sec = NPCX_TTC;
	return sec;
}

void system_set_rtc(uint32_t seconds)
{
	volatile uint16_t __i;

	/* Set MTC counter unit:seconds */
	NPCX_TTC = seconds;

	/* Wait till clock is readable */
	for (__i = 0; __i < MTC_TTC_LOAD_DELAY; ++__i)
		;
}

/* Check reset cause */
void system_check_reset_cause(void)
{
	uint32_t hib_wake_flags = bbram_data_read(BBRM_DATA_INDEX_WAKE);
	uint32_t flags = 0;

	/* Use scratch bit to check power on reset or VCC1_RST reset */
	if (!IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_SCRATCH)) {
#ifdef BOARD_WHEATLEY
		flags |= RESET_FLAG_RESET_PIN;
#else
		/* Check for VCC1 reset */
		if (IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_STS))
			flags |= RESET_FLAG_RESET_PIN;
		else
			flags |= RESET_FLAG_POWER_ON;
#endif
	}<commit_msg>npcx: rtc: Write RTC reg twice to ensure non-volatility<commit_after>/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* System module for Chrome EC : NPCX hardware specific implementation */

#include "clock.h"
#include "common.h"
#include "console.h"
#include "cpu.h"
#include "host_command.h"
#include "registers.h"
#include "system.h"
#include "hooks.h"
#include "task.h"
#include "timer.h"
#include "util.h"
#include "gpio.h"
#include "hwtimer_chip.h"
#include "system_chip.h"
#include "clock_chip.h"
#include "rom_chip.h"

/* Flags for BBRM_DATA_INDEX_WAKE */
#define HIBERNATE_WAKE_MTC        (1 << 0)  /* MTC alarm */
#define HIBERNATE_WAKE_PIN        (1 << 1)  /* Wake pin */

/* Delay after writing TTC for value to latch */
#define MTC_TTC_LOAD_DELAY_US 250
#define MTC_ALARM_MASK     ((1 << 25) - 1)
#define MTC_WUI_GROUP      MIWU_GROUP_4
#define MTC_WUI_MASK       MASK_PIN7

/* ROM address of chip revision */
#define CHIP_REV_ADDR 0x00007FFC

/* Console output macros */
#define CPUTS(outstr) cputs(CC_SYSTEM, outstr)
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)

/* Begin address for the .lpram section; defined in linker script */
uintptr_t __lpram_fw_start = CONFIG_LPRAM_BASE;

/*****************************************************************************/
/* Internal functions */

void system_watchdog_reset(void)
{
	/* Unlock & stop watchdog registers */
	NPCX_WDSDM = 0x87;
	NPCX_WDSDM = 0x61;
	NPCX_WDSDM = 0x63;

	/* Reset TWCFG */
	NPCX_TWCFG = 0;
	/* Select T0IN clock as watchdog prescaler clock */
	SET_BIT(NPCX_TWCFG, NPCX_TWCFG_WDCT0I);

	/* Clear watchdog reset status initially*/
	SET_BIT(NPCX_T0CSR, NPCX_T0CSR_WDRST_STS);

	/* Keep prescaler ratio timer0 clock to 1:1 */
	NPCX_TWCP = 0x00;

	/* Set internal counter and prescaler */
	NPCX_TWDT0 = 0x00;
	NPCX_WDCNT = 0x01;

	/* Disable interrupt */
	interrupt_disable();
	/* Reload and restart Timer 0*/
	SET_BIT(NPCX_T0CSR, NPCX_T0CSR_RST);
	/* Wait for timer is loaded and restart */
	while (IS_BIT_SET(NPCX_T0CSR, NPCX_T0CSR_RST))
		;
	/* Enable interrupt */
	interrupt_enable();
}

/**
 * Read battery-backed ram (BBRAM) at specified index.
 *
 * @return The value of the register or 0 if invalid index.
 */
static uint32_t bbram_data_read(enum bbram_data_index index)
{
	uint32_t value = 0;
	/* Check index */
	if (index < 0 || index >= NPCX_BBRAM_SIZE)
		return 0;

	/* BBRAM is valid */
	if (IS_BIT_SET(NPCX_BKUP_STS, NPCX_BKUP_STS_IBBR))
		return 0;

	/* Read BBRAM */
	value += NPCX_BBRAM(index + 3);
	value = value << 8;
	value += NPCX_BBRAM(index + 2);
	value = value << 8;
	value += NPCX_BBRAM(index + 1);
	value = value << 8;
	value += NPCX_BBRAM(index);

	return value;
}

/**
 * Write battery-backed ram (BBRAM) at specified index.
 *
 * @return nonzero if error.
 */
static int bbram_data_write(enum bbram_data_index index, uint32_t value)
{
	/* Check index */
	if (index < 0 || index >= NPCX_BBRAM_SIZE)
		return EC_ERROR_INVAL;

	/* BBRAM is valid */
	if (IS_BIT_SET(NPCX_BKUP_STS, NPCX_BKUP_STS_IBBR))
		return EC_ERROR_INVAL;

	/* Write BBRAM */
	NPCX_BBRAM(index)     = value & 0xFF;
	NPCX_BBRAM(index + 1) = (value >> 8)  & 0xFF;
	NPCX_BBRAM(index + 2) = (value >> 16) & 0xFF;
	NPCX_BBRAM(index + 3) = (value >> 24) & 0xFF;

	/* Wait for write-complete */
	return EC_SUCCESS;
}

/* MTC functions */
uint32_t system_get_rtc_sec(void)
{
	/* Get MTC counter unit:seconds */
	uint32_t sec = NPCX_TTC;
	return sec;
}

void system_set_rtc(uint32_t seconds)
{
	/*
	 * Set MTC counter unit:seconds, write twice to ensure values
	 * latch to NVMem.
	 */
	NPCX_TTC = seconds;
	udelay(MTC_TTC_LOAD_DELAY_US);
	NPCX_TTC = seconds;
	udelay(MTC_TTC_LOAD_DELAY_US);
}

/* Check reset cause */
void system_check_reset_cause(void)
{
	uint32_t hib_wake_flags = bbram_data_read(BBRM_DATA_INDEX_WAKE);
	uint32_t flags = 0;

	/* Use scratch bit to check power on reset or VCC1_RST reset */
	if (!IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_SCRATCH)) {
#ifdef BOARD_WHEATLEY
		flags |= RESET_FLAG_RESET_PIN;
#else
		/* Check for VCC1 reset */
		if (IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_VCC1_RST_STS))
			flags |= RESET_FLAG_RESET_PIN;
		else
			flags |= RESET_FLAG_POWER_ON;
#endif
	}
{'fraction_non_alphanumeric': 0.13506584314182496, 'fraction_numerical': 0.024356135648525814, 'mean_word_length': 4.081113084665483, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1023650', 'n_tokens_mistral': 3697, 'n_tokens_neox': 3426, 'n_words': 852}