Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6481869f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drivers: qcom: system_pm: read CVAL to program PDC wake up"

parents bcb37f3a a2243008
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@
#define CNTFRQ		0x10
#define CNTP_TVAL	0x28
#define CNTP_CTL	0x2c
#define CNTCVAL_LO	0x30
#define CNTCVAL_HI	0x34
#define CNTV_TVAL	0x38
#define CNTV_CTL	0x3c

@@ -541,6 +543,23 @@ u32 arch_timer_get_rate(void)
	return arch_timer_rate;
}

void arch_timer_mem_get_cval(u32 *lo, u32 *hi)
{
	u32 ctrl;

	*lo = *hi = ~0U;

	if (!arch_counter_base)
		return;

	ctrl = readl_relaxed_no_log(arch_counter_base + CNTV_CTL);

	if (ctrl & ARCH_TIMER_CTRL_ENABLE) {
		*lo = readl_relaxed_no_log(arch_counter_base + CNTCVAL_LO);
		*hi = readl_relaxed_no_log(arch_counter_base + CNTCVAL_HI);
	}
}

static u64 arch_counter_get_cntvct_mem(void)
{
	u32 vct_lo, vct_hi, tmp_hi;
+8 −10
Original line number Diff line number Diff line
@@ -1043,18 +1043,9 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx,
	}

	if (level->notify_rpm) {
		uint64_t us;
		uint32_t pred_us;

		us = get_cluster_sleep_time(cluster, NULL, from_idle,
								&pred_us);

		us = us + 1;

		clear_predict_history();
		clear_cl_predict_history();

		if (system_sleep_enter(us))
		if (system_sleep_enter())
			return -EBUSY;
	}
	/* Notify cluster enter event after successfully config completion */
@@ -1261,6 +1252,13 @@ int get_cluster_id(struct lpm_cluster *cluster, int *aff_lvl)
		state_id |= (level->psci_id & cluster->psci_mode_mask)
					<< cluster->psci_mode_shift;
		(*aff_lvl)++;

		/*
		 * We may have updated the broadcast timers, update
		 * the wakeup value by reading the bc timer directly.
		 */
		if (level->notify_rpm)
			system_sleep_update_wakeup();
	}
unlock_and_return:
	spin_unlock(&cluster->sync_lock);
+20 −28
Original line number Diff line number Diff line
@@ -18,23 +18,35 @@
#include <soc/qcom/rpmh.h>
#include <soc/qcom/system_pm.h>

#define ARCH_TIMER_HZ		(19200000UL)
#include <clocksource/arm_arch_timer.h>

#define PDC_TIME_VALID_SHIFT	31
#define PDC_TIME_UPPER_MASK	0xFFFFFF

static struct rpmh_client *rpmh_client;

static int setup_wakeup(uint64_t sleep_val)
static int setup_wakeup(uint32_t lo, uint32_t hi)
{
	struct tcs_cmd cmd[2] = { { 0 } };

	cmd[0].data = (sleep_val >> 32) & PDC_TIME_UPPER_MASK;
	cmd[0].data =  hi & PDC_TIME_UPPER_MASK;
	cmd[0].data |= 1 << PDC_TIME_VALID_SHIFT;
	cmd[1].data = sleep_val & 0xFFFFFFFF;
	cmd[1].data = lo;

	return rpmh_write_control(rpmh_client, cmd, ARRAY_SIZE(cmd));
}

int system_sleep_update_wakeup(void)
{
	uint32_t lo = ~0U, hi = ~0U;

	/* Read the hardware to get the most accurate value */
	arch_timer_mem_get_cval(&lo, &hi);

	return setup_wakeup(lo, hi);
}
EXPORT_SYMBOL(system_sleep_update_wakeup);

/**
 * system_sleep_allowed() - Returns if its okay to enter system low power modes
 */
@@ -47,35 +59,15 @@ EXPORT_SYMBOL(system_sleep_allowed);
/**
 * system_sleep_enter() - Activties done when entering system low power modes
 *
 * @sleep_val: The sleep duration in us.
 *
 * Returns 0 for success or error values from writing the timer value in the
 * hardware block.
 * Returns 0 for success or error values from writing the sleep/wake values to
 * the hardware block.
 */
int system_sleep_enter(uint64_t sleep_val)
int system_sleep_enter(void)
{
	int ret;

	if (IS_ERR_OR_NULL(rpmh_client))
		return -EFAULT;

	ret = rpmh_flush(rpmh_client);
	if (ret)
		return ret;

	/*
	 * Set up the wake up value offset from the current time.
	 * Convert us to ns to allow div by 19.2 Mhz tick timer.
	 */
	if (sleep_val) {
		sleep_val *= NSEC_PER_USEC;
		do_div(sleep_val, NSEC_PER_SEC/ARCH_TIMER_HZ);
		sleep_val += arch_counter_get_cntvct();
	} else {
		sleep_val = ~0ULL;
	}

	return setup_wakeup(sleep_val);
	return rpmh_flush(rpmh_client);
}
EXPORT_SYMBOL(system_sleep_enter);

+5 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ struct arch_timer_kvm_info {
extern u32 arch_timer_get_rate(void);
extern u64 (*arch_timer_read_counter)(void);
extern struct arch_timer_kvm_info *arch_timer_get_kvm_info(void);

extern void arch_timer_mem_get_cval(u32 *lo, u32 *hi);
#else

static inline u32 arch_timer_get_rate(void)
@@ -72,6 +72,10 @@ static inline u64 arch_timer_read_counter(void)
	return 0;
}

static void arch_timer_mem_get_cval(u32 *lo, u32 *hi)
{
	*lo = *hi = ~0U;
}
#endif

#endif
+7 −2
Original line number Diff line number Diff line
@@ -14,13 +14,15 @@
#define __SOC_QCOM_SYS_PM_H__

#ifdef CONFIG_QTI_SYSTEM_PM
int system_sleep_enter(uint64_t sleep_val);
int system_sleep_enter(void);

void system_sleep_exit(void);

bool system_sleep_allowed(void);

int system_sleep_update_wakeup(void);
#else
static inline int system_sleep_enter(uint64_t sleep_val)
static inline int system_sleep_enter(void)
{ return -ENODEV; }

static inline void system_sleep_exit(void)
@@ -29,6 +31,9 @@ static inline void system_sleep_exit(void)
static inline bool system_sleep_allowed(void)
{ return false; }

static inline int system_sleep_update_wakeup(void)
{ return -ENODEV; }

#endif /* CONFIG_QTI_SYSTEM_PM */

#endif /* __SOC_QCOM_SYS_PM_H__ */