static unsigned long __calc_values(struct alpha_pll_clk *pll,
		unsigned long rate, int *l_val, u64 *a_val, bool round_up)
{
	u32 parent_rate;
	u64 remainder;
	u64 quotient;
	unsigned long freq_hz;
	int alpha_bw = ALPHA_BITWIDTH;

	parent_rate = clk_get_rate(pll->c.parent);
	quotient = rate;
	remainder = do_div(quotient, parent_rate);
	*l_val = quotient;

	if (!remainder) {
		*a_val = 0;
		return rate;
	}

	if (pll->is_fabia)
		alpha_bw = FABIA_ALPHA_BITWIDTH;

	/* Upper ALPHA_BITWIDTH bits of Alpha */
	quotient = remainder << alpha_bw;
	remainder = do_div(quotient, parent_rate);

	if (remainder && round_up)
		quotient++;

	*a_val = quotient;
	freq_hz = compute_rate(pll, *l_val, *a_val);
	return freq_hz;
}
static enum handoff alpha_pll_handoff(struct clk *c)
{
	struct alpha_pll_clk *pll = to_alpha_pll_clk(c);
	struct alpha_pll_masks *masks = pll->masks;
	u64 a_val;
	u32 alpha_en, l_val, regval;

	/* Set the PLL_HW_UPDATE_LOGIC_BYPASS bit before continuing */
	if (pll->dynamic_update) {
		regval = readl_relaxed(MODE_REG(pll));
		regval |= ALPHA_PLL_HW_UPDATE_LOGIC_BYPASS;
		writel_relaxed(regval, MODE_REG(pll));
	}

	update_vco_tbl(pll);

	if (!is_locked(pll)) {
		if (pll->slew) {
			if (c->rate && dyna_alpha_pll_set_rate(c, c->rate))
				WARN(1, "%s: Failed to configure rate\n",
					c->dbg_name);
		} else {
			if (c->rate && alpha_pll_set_rate(c, c->rate))
				WARN(1, "%s: Failed to configure rate\n",
					c->dbg_name);
		}
		__init_alpha_pll(c);
		return HANDOFF_DISABLED_CLK;
	} else if (pll->fsm_en_mask && !is_fsm_mode(MODE_REG(pll))) {
		WARN(1, "%s should be in FSM mode but is not\n", c->dbg_name);
	}

	l_val = readl_relaxed(L_REG(pll));
	/* read u64 in two steps to satisfy alignment constraint */
	a_val = readl_relaxed(A_REG(pll) + 0x4);
	a_val = a_val << 32 | readl_relaxed(A_REG(pll));
	/* get upper 32 bits */
	a_val = a_val >> (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);

	alpha_en = readl_relaxed(ALPHA_EN_REG(pll));
	alpha_en &= masks->alpha_en_mask;
	if (!alpha_en)
		a_val = 0;

	c->rate = compute_rate(pll, l_val, a_val);

	/*
	 * Unconditionally vote for the PLL; it might be on because of
	 * another master's vote.
	 */
	if (pll->fsm_en_mask)
		__alpha_pll_vote_enable(pll);

	return HANDOFF_ENABLED_CLK;
}
예제 #3
0
        void init(u8 spi_int_priority, bool fast_spi_irq, u8 aux_int_priority, bool fast_aux_irq)
        {
            // deselect all devices
            select_device(select::none);

            regs.master_control.spi_1_clock_enable = true;
            regs.master_control.spi_1_pin_control = true;
            
            regs.global_control.enable = true;
            regs.global_control.reset = true; // reset must be done after controller is enabled
            regs.global_control.reset = false;

            // Aux controller supports up to 16.6 mbps. If the other devices cannot go as high, we may need to reprogram the rate for each transfer depending on the target
            //regs.control.rate = compute_rate(16100000); // effective rate will be 12.5Mbps, this divider is applied directly on the h_clock, so it's not very precise for high rates
            regs.control.rate = compute_rate(8000000);
            regs.control.master = true;
            regs.control.bitnum = 0xF; // 16 bits
            regs.control.shift_off = false; // enable the clock output
            regs.control.thr = 0; // select no threshold (interrupt as soon as 1 entry in FIFO)
            regs.control.mode = 1; // clock starts low, data sampled on falling edge
            regs.control.lsb_first = false; // send most significant bit first
            regs.control.bhalt = false; // don't use the busy signal
            regs.control.unidir = true; // bidirectional
            regs.control.rxtx = 1; // output at all times, we don't mux the pin

            regs.frame_count = 0; // single frame sent, no block transfers

            regs.interrupt.intthr = true;
            regs.interrupt.inteot = true;

            regs.timer_control.mode = 0;
            regs.timer_control.pirqe = 1;
            regs.timer_control.tirqe = 0;

            // register the SPI interrupt handler - we don't need it yet, our only spi device is the aux controller which sends us an interrupt on its own. for the IMU, this may change.
            //get_int_ctrl().install_service_routine(interrupt::id::spi_1, spi_int_priority, fast_spi_irq, interrupt::trigger::high_level, static_spi_isr);
            //get_int_ctrl().enable_interrupt(interrupt::id::spi_1);

            // register the auxiliary controller interrupt handler (tells us when data is ready)
            get_int_ctrl().install_service_routine(interrupt::id::aux_ctrl_spi, aux_int_priority, fast_aux_irq, interrupt::trigger::positive_edge, static_aux_isr);
            get_int_ctrl().enable_interrupt(interrupt::id::aux_ctrl_spi);
        }
static enum handoff fabia_alpha_pll_handoff(struct clk *c)
{
	struct alpha_pll_clk *pll = to_alpha_pll_clk(c);
	u64 a_val;
	u32 l_val, regval;

	/* Set the PLL_HW_UPDATE_LOGIC_BYPASS bit before continuing */
	regval = readl_relaxed(MODE_REG(pll));
	regval |= ALPHA_PLL_HW_UPDATE_LOGIC_BYPASS;
	writel_relaxed(regval, MODE_REG(pll));

	if (!is_locked(pll)) {
		if (c->rate && fabia_alpha_pll_set_rate(c, c->rate))
			WARN(1, "%s: Failed to configure rate\n", c->dbg_name);
		__init_alpha_pll(c);
		return HANDOFF_DISABLED_CLK;
	} else if (pll->fsm_en_mask && !is_fsm_mode(MODE_REG(pll))) {
		WARN(1, "%s should be in FSM mode but is not\n", c->dbg_name);
	}

	l_val = readl_relaxed(FABIA_L_REG(pll));

	if (pll->fabia_frac_offset)
		a_val = readl_relaxed(FABIA_FRAC_OFF(pll));
	else
		a_val = readl_relaxed(FABIA_FRAC_REG(pll));

	c->rate = compute_rate(pll, l_val, a_val);

	/*
	 * Unconditionally vote for the PLL; it might be on because of
	 * another master's vote.
	 */
	if (pll->fsm_en_mask)
		__alpha_pll_vote_enable(pll);

	return HANDOFF_ENABLED_CLK;
}
예제 #5
0
void compute_estimation(aodv_neigh *tmp_neigh) {

	int recv_delay;
	//Nominal rate computation
	//Add last own transmission delay measured by our neighbour
	tmp_neigh->ett.count_rcv++;
	
	if (tmp_neigh->ett.count_rcv == tmp_neigh->ett.ett_window) { //Let's compute the estimation!
		recv_delay = compute_delay(tmp_neigh);
		
		if (recv_delay == 0 && tmp_neigh->ett.ett_window == ETT_PROBES_MAX) {
			if (tmp_neigh->ett.reset) { //Second consectutive round without an estimation!
#ifdef DEBUG
				printk(
						"Capacity Estimation with %s is not possible - Second: Resetting\n",
						inet_ntoa(tmp_neigh->ip));
#endif
				reset_ett(tmp_neigh);

			} else { //First round without an estimation!
#ifdef DEBUG
				printk(
						"Capacity Estimation with %s is not possible - First: Using last measured values\n",
						inet_ntoa(tmp_neigh->ip));
#endif
				//lets start a new measurements round
				delay_vector_init(&(tmp_neigh->ett.recv_delays[0]));
				tmp_neigh->ett.count_rcv = 0;
				tmp_neigh->ett.ett_window = ETT_PROBES_MIN;
				tmp_neigh->ett.reset = 1;

			}
			send_ett_info(tmp_neigh, tmp_neigh->send_rate, FALSE);
			return;
		}

		if (recv_delay == 0) {
			//Increase the size of the estimation window
			tmp_neigh->ett.ett_window += 2; //lets do two more measurements
			if (tmp_neigh->ett.ett_window > ETT_PROBES_MAX)
				tmp_neigh->ett.ett_window=ETT_PROBES_MAX;
			return;
		}

		if (recv_delay == DEFAULT_ETT_METRIC) {
#ifdef DEBUG
			printk(
					"%s does not receive my ETT_PROBES: Capacity Estimation is not possible - Resetting ETT...\n",
					inet_ntoa(tmp_neigh->ip));
#endif
			reset_ett(tmp_neigh);
			return;
		}
		//lets start a new measurement round
		delay_vector_init(&(tmp_neigh->ett.recv_delays[0]));
		tmp_neigh->ett.count_rcv = 0;
		tmp_neigh->ett.ett_window = ETT_PROBES_MIN;
		tmp_neigh->ett.reset = 0;
		tmp_neigh->send_rate = compute_rate(recv_delay);
		send_ett_info(tmp_neigh, tmp_neigh->send_rate, FALSE);
	}

}