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

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

Merge "clk: qcom: clk-cpu-osm: handle corner cases for APM/MEM-ACC switching"

parents 39b4e083 d1a1e24a
Loading
Loading
Loading
Loading
+56 −10
Original line number Diff line number Diff line
@@ -84,12 +84,14 @@ enum clk_osm_trace_packet_id {
#define VERSION_REG					0x0

#define OSM_TABLE_SIZE					40
#define MAX_VIRTUAL_CORNER				(OSM_TABLE_SIZE - 1)
#define MAX_CLUSTER_CNT					2
#define LLM_SW_OVERRIDE_CNT				3
#define CORE_COUNT_VAL(val)			((val & GENMASK(18, 16)) >> 16)
#define SINGLE_CORE					1
#define MAX_CORE_COUNT					4
#define DEBUG_REG_NUM					3
#define OSM_SEQ_MINUS_ONE				0xff

#define ENABLE_REG					0x1004
#define INDEX_REG					0x1150
@@ -353,8 +355,10 @@ struct clk_osm {
	u32 cluster_num;
	u32 irq;
	u32 apm_crossover_vc;
	u32 apm_threshold_pre_vc;
	u32 apm_threshold_vc;
	u32 mem_acc_crossover_vc;
	u32 mem_acc_threshold_pre_vc;
	u32 mem_acc_threshold_vc;
	u32 cycle_counter_reads;
	u32 cycle_counter_delay;
@@ -1622,10 +1626,26 @@ static int clk_osm_resolve_crossover_corners(struct clk_osm *c,

		if (corner_volt >= apm_threshold) {
			c->apm_threshold_vc = c->osm_table[i].virtual_corner;
			/*
			 * Handle case where VC 0 has open-loop
			 * greater than or equal to APM threshold voltage.
			 */
			c->apm_threshold_pre_vc = c->apm_threshold_vc ?
				c->apm_threshold_vc - 1 : OSM_SEQ_MINUS_ONE;
			break;
		}
	}

	/*
	 * This assumes the OSM table uses corners
	 * 0 to MAX_VIRTUAL_CORNER - 1.
	 */
	if (!c->apm_threshold_vc &&
	    c->apm_threshold_pre_vc != OSM_SEQ_MINUS_ONE) {
		c->apm_threshold_vc = MAX_VIRTUAL_CORNER;
		c->apm_threshold_pre_vc = c->apm_threshold_vc - 1;
	}

	/* Determine MEM ACC threshold virtual corner */
	if (mem_acc_threshold) {
		for (i = 0; i < OSM_TABLE_SIZE; i++) {
@@ -1636,9 +1656,30 @@ static int clk_osm_resolve_crossover_corners(struct clk_osm *c,
			if (corner_volt >= mem_acc_threshold) {
				c->mem_acc_threshold_vc
					= c->osm_table[i].virtual_corner;
				/*
				 * Handle case where VC 0 has open-loop
				 * greater than or equal to MEM-ACC threshold
				 * voltage.
				 */
				c->mem_acc_threshold_pre_vc =
					c->mem_acc_threshold_vc ?
					c->mem_acc_threshold_vc - 1 :
					OSM_SEQ_MINUS_ONE;
				break;
			}
		}

		/*
		 * This assumes the OSM table uses corners
		 * 0 to MAX_VIRTUAL_CORNER - 1.
		 */
		if (!c->mem_acc_threshold_vc && c->mem_acc_threshold_pre_vc
		    != OSM_SEQ_MINUS_ONE) {
			c->mem_acc_threshold_vc =
				MAX_VIRTUAL_CORNER;
			c->mem_acc_threshold_pre_vc =
				c->mem_acc_threshold_vc - 1;
		}
	}

	return 0;
@@ -1989,14 +2030,21 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c)
		 * highest MEM ACC threshold if it is specified instead of the
		 * fixed mapping in the LUT.
		 */
		if (c->mem_acc_threshold_vc) {
			threshold_vc[2] = c->mem_acc_threshold_vc - 1;
		if (c->mem_acc_threshold_vc || c->mem_acc_threshold_pre_vc
		    == OSM_SEQ_MINUS_ONE) {
			threshold_vc[2] = c->mem_acc_threshold_pre_vc;
			threshold_vc[3] = c->mem_acc_threshold_vc;

			if (c->mem_acc_threshold_pre_vc == OSM_SEQ_MINUS_ONE) {
				threshold_vc[1] = threshold_vc[0] =
					c->mem_acc_threshold_pre_vc;
			} else {
				if (threshold_vc[1] >= threshold_vc[2])
					threshold_vc[1] = threshold_vc[2] - 1;
				if (threshold_vc[0] >= threshold_vc[1])
					threshold_vc[0] = threshold_vc[1] - 1;
			}
		}

		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(55),
						threshold_vc[0]);
@@ -2249,8 +2297,7 @@ static void clk_osm_apm_vc_setup(struct clk_osm *c)
		clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(1),
							  SEQ_REG(8));
		clk_osm_write_reg(c, c->apm_threshold_vc, SEQ_REG(15));
		clk_osm_write_reg(c, c->apm_threshold_vc != 0 ?
					  c->apm_threshold_vc - 1 : 0xff,
		clk_osm_write_reg(c, c->apm_threshold_pre_vc,
					  SEQ_REG(31));
		clk_osm_write_reg(c, 0x3b | c->apm_threshold_vc << 6,
							  SEQ_REG(73));
@@ -2268,8 +2315,7 @@ static void clk_osm_apm_vc_setup(struct clk_osm *c)
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(15),
					     c->apm_threshold_vc);
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(31),
				     c->apm_threshold_vc != 0 ?
				     c->apm_threshold_vc - 1 : 0xff);
				     c->apm_threshold_pre_vc);
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(76),
				     0x39 | c->apm_threshold_vc << 6);
	}