Ejemplo n.º 1
0
/** Set DPLLs 1,2,3,4,5 to ON (locked) and autoidle.
 * @param device Register map.
 *
 * The idea is to get all DPLLs running and make hw control their power mode,
 * based on the module requirements (module ICLKs and FCLKs).
 */
void amdm37x_setup_dpll_on_autoidle(amdm37x_t *device)
{
	assert(device);
	/* Get SYS_CLK value, it is used as reference clock by all DPLLs,
	 * NFI who sets this or why it is set to specific value. */
	const unsigned osc_clk = pio_read_32(&device->prm.clocks->clksel)
	    & CLOCK_CONTROL_PRM_CLKSEL_SYS_CLKIN_MASK;
	const unsigned clk_reg = pio_read_32(&device->prm.global->clksrc_ctrl);
	const unsigned base_freq = sys_clk_freq_kHz(osc_clk)
	    / GLOBAL_REG_PRM_CLKSRC_CTRL_SYSCLKDIV_GET(clk_reg);
	ddf_msg(LVL_NOTE, "Base frequency: %d.%dMhz",
	    base_freq / 1000, base_freq % 1000);


	/* DPLL1 provides MPU(CPU) clock.
	 * It uses SYS_CLK as reference clock and core clock (DPLL3) as
	 * high frequency bypass (MPU then runs on L3 interconnect freq).
	 * It should be setup by fw or u-boot.*/
	mpu_cm_regs_t *mpu = device->cm.mpu;

	/* Current MPU frequency. */
	if (pio_read_32(&mpu->clkstst) & MPU_CM_CLKSTST_CLKACTIVITY_MPU_ACTIVE_FLAG) {
		if (pio_read_32(&mpu->idlest_pll) & MPU_CM_IDLEST_PLL_ST_MPU_CLK_LOCKED_FLAG) {
			/* DPLL active and locked */
			const uint32_t reg = pio_read_32(&mpu->clksel1_pll);
			const unsigned multiplier =
			    (reg & MPU_CM_CLKSEL1_PLL_MPU_DPLL_MULT_MASK)
				>> MPU_CM_CLKSEL1_PLL_MPU_DPLL_MULT_SHIFT;
			const unsigned divisor =
			    (reg & MPU_CM_CLKSEL1_PLL_MPU_DPLL_DIV_MASK)
				>> MPU_CM_CLKSEL1_PLL_MPU_DPLL_DIV_SHIFT;
			const unsigned divisor2 =
			    (pio_read_32(&mpu->clksel2_pll)
			        & MPU_CM_CLKSEL2_PLL_MPU_DPLL_CLKOUT_DIV_MASK);
			if (multiplier && divisor && divisor2) {
				/** See AMDM37x TRM p. 300 for the formula */
				const unsigned freq =
				    ((base_freq * multiplier) / (divisor + 1))
				    / divisor2;
				ddf_msg(LVL_NOTE, "MPU running at %d.%d MHz",
				    freq / 1000, freq % 1000);
			} else {
				ddf_msg(LVL_WARN, "Frequency divisor and/or "
				    "multiplier value invalid: %d %d %d",
				    multiplier, divisor, divisor2);
			}
		} else {
			/* DPLL in LP bypass mode */
			const unsigned divisor =
			    MPU_CM_CLKSEL1_PLL_MPU_CLK_SRC_VAL(
			        pio_read_32(&mpu->clksel1_pll));
			ddf_msg(LVL_NOTE, "MPU DPLL in bypass mode, running at"
			    " CORE CLK / %d MHz", divisor);
		}
	} else {
Ejemplo n.º 2
0
uint32_t hda_reg32_read(uint32_t *r)
{
	return uint32_t_le2host(pio_read_32(r));
}
Ejemplo n.º 3
0
/** Debug function, checks consistency of memory structures.
 *
 * @param[in] arg UHCI structure to use.
 * @return EOK (should never return)
 */
int hc_debug_checker(void *arg)
{
	hc_t *instance = arg;
	assert(instance);

#define QH(queue) \
	instance->transfers_##queue.queue_head

	while (1) {
		const uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
		const uint16_t sts = pio_read_16(&instance->registers->usbsts);
		const uint16_t intr =
		    pio_read_16(&instance->registers->usbintr);

		if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) {
			usb_log_debug2("Command: %X Status: %X Intr: %x\n",
			    cmd, sts, intr);
		}

		const uintptr_t frame_list =
		    pio_read_32(&instance->registers->flbaseadd) & ~0xfff;
		if (frame_list != addr_to_phys(instance->frame_list)) {
			usb_log_debug("Framelist address: %p vs. %p.\n",
			    (void *) frame_list,
			    (void *) addr_to_phys(instance->frame_list));
		}

		int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff;

		uintptr_t expected_pa = instance->frame_list[frnum]
		    & LINK_POINTER_ADDRESS_MASK;
		uintptr_t real_pa = addr_to_phys(QH(interrupt));
		if (expected_pa != real_pa) {
			usb_log_debug("Interrupt QH: %p (frame %d) vs. %p.\n",
			    (void *) expected_pa, frnum, (void *) real_pa);
		}

		expected_pa = QH(interrupt)->next & LINK_POINTER_ADDRESS_MASK;
		real_pa = addr_to_phys(QH(control_slow));
		if (expected_pa != real_pa) {
			usb_log_debug("Control Slow QH: %p vs. %p.\n",
			    (void *) expected_pa, (void *) real_pa);
		}

		expected_pa = QH(control_slow)->next & LINK_POINTER_ADDRESS_MASK;
		real_pa = addr_to_phys(QH(control_full));
		if (expected_pa != real_pa) {
			usb_log_debug("Control Full QH: %p vs. %p.\n",
			    (void *) expected_pa, (void *) real_pa);
		}

		expected_pa = QH(control_full)->next & LINK_POINTER_ADDRESS_MASK;
		real_pa = addr_to_phys(QH(bulk_full));
		if (expected_pa != real_pa ) {
			usb_log_debug("Bulk QH: %p vs. %p.\n",
			    (void *) expected_pa, (void *) real_pa);
		}
		async_usleep(UHCI_DEBUGER_TIMEOUT);
	}
	return EOK;
#undef QH
}