예제 #1
0
파일: clock.c 프로젝트: KGG814/AOS
static freq_t
_spi_set_freq(clk_t* clk, freq_t hz)
{
    freq_t fin;
    int clkid;
    int rpre, r;
    clkid = exynos_clk_get_priv_id(clk);
    switch (clk->id) {
    case CLK_SPI0_ISP:
        clkid += 32;
        break;
    case CLK_SPI1_ISP:
        clkid += 35;
        break;
    case CLK_SPI0:
        clkid += 12;
        break;
    case CLK_SPI1:
        clkid += 15;
        break;
    case CLK_SPI2:
        clkid += 18;
        break;
    default:
        return 0;
    }
    fin = clk_get_freq(clk->parent);
    rpre = fin / 0xf / hz;
    r = fin / (rpre + 1) / hz;
    exynos_cmu_set_div(_clk_regs, clkid, 1, r);
    exynos_cmu_set_div(_clk_regs, clkid + 2, 2, rpre);
    return clk_get_freq(clk);
}
예제 #2
0
파일: clock.c 프로젝트: KGG814/AOS
static freq_t
_peric_clk_set_freq(clk_t* clk, freq_t hz)
{
    freq_t fin;
    int clkid;
    int div;
    fin = clk_get_freq(clk->parent);
    div = fin / hz;
    clkid = exynos_clk_get_priv_id(clk);
    /* The DIV register has an additional 2 word offset */
    clkid += 16;
    exynos_cmu_set_div(_clk_regs, clkid, 1, div);
    return clk_get_freq(clk);
}
예제 #3
0
파일: clock.c 프로젝트: gapry/AOS
void
clk_print_tree(clk_t* clk, char* prefix)
{
    int depth = strlen(prefix);
    char new_prefix[depth + 2];
    strcpy(new_prefix, prefix);
    strcpy(new_prefix + depth, "|");
    while (clk != NULL) {
        const char* units[] = {"hz", "Khz", "Mhz", "Ghz"};
        const char** u = units;
        float freq = clk_get_freq(clk);
        /* Find frequency with appropriate units */
        while(freq > 10000){
            freq/= 1000;
            u++;
        }
        /* Generate tree graphics */
        if (clk->sibling == NULL) {
            strcpy(new_prefix + depth, " ");
        }
        printf("%s\\%s (%0.1f %s)\n", new_prefix, clk->name, freq, *u);
        clk_print_tree(clk->child, new_prefix);
        clk = clk->sibling;
    }
}
예제 #4
0
파일: clock.c 프로젝트: KGG814/AOS
/* The SPI div register is a special case as we have 2 dividers, one of which
 * is 2 nibbles wide */
static freq_t
_spi_get_freq(clk_t* clk)
{
    freq_t fin;
    int clkid;
    int rpre, r;
    clkid = exynos_clk_get_priv_id(clk);
    switch (clk->id) {
    case CLK_SPI0_ISP:
        clkid += 32;
        break;
    case CLK_SPI1_ISP:
        clkid += 35;
        break;
    case CLK_SPI0:
        clkid += 12;
        break;
    case CLK_SPI1:
        clkid += 15;
        break;
    case CLK_SPI2:
        clkid += 18;
        break;
    default:
        return 0;
    }
    r = exynos_cmu_get_div(_clk_regs, clkid, 1);
    rpre = exynos_cmu_get_div(_clk_regs, clkid + 2, 2);
    fin = clk_get_freq(clk->parent);
    return fin / (r + 1) / (rpre + 1);
}
예제 #5
0
static int
jzsmb_attach(device_t dev)
{
	struct jzsmb_softc *sc;
	phandle_t node;
	int error;

	sc = device_get_softc(dev);
	node = ofw_bus_get_node(dev);
	mtx_init(&sc->mtx, device_get_nameunit(dev), "jzsmb", MTX_DEF);

	error = clk_get_by_ofw_index(dev, 0, 0, &sc->clk);
	if (error != 0) {
		device_printf(dev, "cannot get clock\n");
		goto fail;
	}
	error = clk_enable(sc->clk);
	if (error != 0) {
		device_printf(dev, "cannot enable clock\n");
		goto fail;
	}
	error = clk_get_freq(sc->clk, &sc->bus_freq);
	if (error != 0 || sc->bus_freq == 0) {
		device_printf(dev, "cannot get bus frequency\n");
		return (error);
	}

	if (bus_alloc_resources(dev, jzsmb_spec, &sc->res) != 0) {
		device_printf(dev, "cannot allocate resources for device\n");
		error = ENXIO;
		goto fail;
	}

	if (OF_getencprop(node, "clock-frequency", &sc->i2c_freq,
	    sizeof(sc->i2c_freq)) != 0 || sc->i2c_freq == 0)
		sc->i2c_freq = 100000;	/* Default to standard mode */

	sc->iicbus = device_add_child(dev, "iicbus", -1);
	if (sc->iicbus == NULL) {
		device_printf(dev, "cannot add iicbus child device\n");
		error = ENXIO;
		goto fail;
	}

	bus_generic_attach(dev);

	return (0);

fail:
	bus_release_resources(dev, jzsmb_spec, &sc->res);
	if (sc->clk != NULL)
		clk_release(sc->clk);
	mtx_destroy(&sc->mtx);
	return (error);
}
예제 #6
0
파일: clock.c 프로젝트: KGG814/AOS
static freq_t
_peric_clk_get_freq(clk_t* clk)
{
    freq_t fin;
    int clkid;
    int div;
    clkid = exynos_clk_get_priv_id(clk);
    /* The DIV register has an additional 2 word offset */
    clkid += 16;
    div = exynos_cmu_get_div(_clk_regs, clkid, 1);
    fin = clk_get_freq(clk->parent);
    return fin / (div + 1);
}
예제 #7
0
static freq_t
_pll_set_freq(clk_t* clk, freq_t hz)
{
    volatile uint32_t* ctrl_reg;
    volatile uint32_t* cfg_reg;
    uint32_t status_mask;
    uint32_t fin;
    uint8_t fdiv;

    fin = clk_get_freq(clk->parent);
    fdiv = fin / hz;
    fdiv = INRANGE(PLL_CTRL_FDIV_MIN, fdiv, PLL_CTRL_FDIV_MAX);

    status_mask = _decode_pll(clk, &ctrl_reg, &cfg_reg);
    if (status_mask == 0) {
        return 0;
    }

    /* Program the feedback divider value and the configuration register */
    *ctrl_reg &= ~(PLL_CTRL_FDIV_MASK);
    *ctrl_reg |= PLL_CTRL_FDIV(fdiv);
    *cfg_reg = pll_cfg_tbl[fdiv - PLL_CTRL_FDIV_MIN].pll_cfg;

    /* Force the PLL into bypass mode */
    *ctrl_reg |= PLL_CTRL_BYPASS_FORCE;

    /* Assert and de-assert the PLL reset */
    *ctrl_reg |= PLL_CTRL_RESET;
    *ctrl_reg &= ~(PLL_CTRL_RESET);

    /* Verify that the PLL is locked */
    while (!(clk_regs->pll_status & status_mask));

    /* Disable the PLL bypass mode */
    *ctrl_reg &= ~(PLL_CTRL_BYPASS_FORCE);

    return clk_get_freq(clk);
}
예제 #8
0
static int
tegra_uart_probe(device_t dev)
{
	struct tegra_softc *sc;
	phandle_t node;
	uint64_t freq;
	int shift;
	int rv;
	const struct ofw_compat_data *cd;

	sc = device_get_softc(dev);
	if (!ofw_bus_status_okay(dev))
		return (ENXIO);
	cd = ofw_bus_search_compatible(dev, compat_data);
	if (cd->ocd_data == 0)
		return (ENXIO);
	sc->ns8250_base.base.sc_class = (struct uart_class *)cd->ocd_data;

	rv = hwreset_get_by_ofw_name(dev, "serial", &sc->reset);
	if (rv != 0) {
		device_printf(dev, "Cannot get 'serial' reset\n");
		return (ENXIO);
	}
	rv = hwreset_deassert(sc->reset);
	if (rv != 0) {
		device_printf(dev, "Cannot unreset 'serial' reset\n");
		return (ENXIO);
	}

	node = ofw_bus_get_node(dev);
	shift = uart_fdt_get_shift1(node);
	rv = clk_get_by_ofw_index(dev, 0, &sc->clk);
	if (rv != 0) {
		device_printf(dev, "Cannot get UART clock: %d\n", rv);
		return (ENXIO);
	}
	rv = clk_enable(sc->clk);
	if (rv != 0) {
		device_printf(dev, "Cannot enable UART clock: %d\n", rv);
		return (ENXIO);
	}
	rv = clk_get_freq(sc->clk, &freq);
	if (rv != 0) {
		device_printf(dev, "Cannot enable UART clock: %d\n", rv);
		return (ENXIO);
	}
	device_printf(dev, "got UART clock: %lld\n", freq);
	return (uart_bus_probe(dev, shift, (int)freq, 0, 0));
}
예제 #9
0
static int
jz4780_uart_probe(device_t dev)
{
    struct jz4780_uart_softc *sc;
    uint64_t freq;
    int shift;
    int rv;
    const struct ofw_compat_data *cd;

    sc = device_get_softc(dev);
    if (!ofw_bus_status_okay(dev))
        return (ENXIO);
    cd = ofw_bus_search_compatible(dev, compat_data);
    if (cd->ocd_data == 0)
        return (ENXIO);

    /* Figure out clock setup */
    rv = clk_get_by_ofw_name(dev, 0, "module", &sc->clk_mod);
    if (rv != 0) {
        device_printf(dev, "Cannot get UART clock: %d\n", rv);
        return (ENXIO);
    }
    rv = clk_enable(sc->clk_mod);
    if (rv != 0) {
        device_printf(dev, "Cannot enable UART clock: %d\n", rv);
        return (ENXIO);
    }
    rv = clk_get_by_ofw_name(dev, 0, "baud", &sc->clk_baud);
    if (rv != 0) {
        device_printf(dev, "Cannot get UART clock: %d\n", rv);
        return (ENXIO);
    }
    rv = clk_enable(sc->clk_baud);
    if (rv != 0) {
        device_printf(dev, "Cannot enable UART clock: %d\n", rv);
        return (ENXIO);
    }
    rv = clk_get_freq(sc->clk_baud, &freq);
    if (rv != 0) {
        device_printf(dev, "Cannot determine UART clock frequency: %d\n", rv);
        return (ENXIO);
    }

    if (bootverbose)
        device_printf(dev, "got UART clock: %lld\n", freq);
    sc->ns8250_base.base.sc_class = (struct uart_class *)cd->ocd_data;
    shift = jz4780_uart_get_shift(dev);
    return (uart_bus_probe(dev, shift, (int)freq, 0, 0));
}
예제 #10
0
/* PLLs */
static freq_t
_pll_get_freq(clk_t* clk)
{
    volatile uint32_t* ctrl_reg;
    volatile uint32_t* cfg_reg;
    uint32_t status_mask;
    uint8_t fdiv;
    uint32_t fin, fout;

    status_mask = _decode_pll(clk, &ctrl_reg, &cfg_reg);
    if (status_mask == 0) {
        return 0;
    }

    fin = clk_get_freq(clk->parent);
    fdiv = (*ctrl_reg & PLL_CTRL_FDIV_MASK) >> PLL_CTRL_FDIV_SHIFT;
    fout = fin * fdiv;

    return fout;
}
예제 #11
0
static void
process_msg(struct tegra_xhci_softc *sc, uint32_t req_cmd, uint32_t req_data,
    uint32_t *resp_cmd, uint32_t *resp_data)
{
	uint64_t freq;
	int rv;

	/* In most cases, data are echoed back. */
	*resp_data = req_data;
	switch (req_cmd) {
	case MBOX_CMD_INC_FALC_CLOCK:
	case MBOX_CMD_DEC_FALC_CLOCK:
		rv = clk_set_freq(sc->clk_xusb_falcon_src, req_data * 1000ULL,
		    0);
		if (rv == 0) {
			rv = clk_get_freq(sc->clk_xusb_falcon_src, &freq);
			*resp_data = (uint32_t)(freq / 1000);
		}
		*resp_cmd = rv == 0 ? MBOX_CMD_ACK: MBOX_CMD_NAK;
		break;

	case MBOX_CMD_INC_SSPI_CLOCK:
	case MBOX_CMD_DEC_SSPI_CLOCK:
		rv = clk_set_freq(sc->clk_xusb_ss, req_data * 1000ULL,
		    0);
		if (rv == 0) {
			rv = clk_get_freq(sc->clk_xusb_ss, &freq);
			*resp_data = (uint32_t)(freq / 1000);
		}
		*resp_cmd = rv == 0 ? MBOX_CMD_ACK: MBOX_CMD_NAK;
		break;

	case MBOX_CMD_SET_BW:
		/* No respense is expected. */
		*resp_cmd = 0;
		break;

	case MBOX_CMD_SET_SS_PWR_GATING:
	case MBOX_CMD_SET_SS_PWR_UNGATING:
		*resp_cmd = MBOX_CMD_NAK;
		break;

	case MBOX_CMD_SAVE_DFE_CTLE_CTX:
		/* Not implemented yet. */
		*resp_cmd = MBOX_CMD_ACK;
		break;


	case MBOX_CMD_START_HSIC_IDLE:
	case MBOX_CMD_STOP_HSIC_IDLE:
		/* Not implemented yet. */
		*resp_cmd = MBOX_CMD_NAK;
		break;

	case MBOX_CMD_DISABLE_SS_LFPS_DETECTION:
	case MBOX_CMD_ENABLE_SS_LFPS_DETECTION:
		/* Not implemented yet. */
		*resp_cmd = MBOX_CMD_NAK;
		break;

	case MBOX_CMD_AIRPLANE_MODE_ENABLED:
	case MBOX_CMD_AIRPLANE_MODE_DISABLED:
	case MBOX_CMD_DBC_WAKE_STACK:
	case MBOX_CMD_HSIC_PRETEND_CONNECT:
	case MBOX_CMD_RESET_SSPI:
		device_printf(sc->dev,
		    "Received unused/unexpected command: %u\n", req_cmd);
		*resp_cmd = 0;
		break;

	default:
		device_printf(sc->dev,
		    "Received unknown command: %u\n", req_cmd);
	}
}
예제 #12
0
struct eth_driver*
ethif_plat_init(int dev_id, struct ethif_os_interface interface) {
    struct enet * enet;
    struct ocotp * ocotp;
    struct clock* arm_clk;
    struct imx6_eth_data *eth_data;
    struct ldesc* ldesc;
    (void)dev_id;

    os_iface_init(interface);

    eth_data = (struct imx6_eth_data*)os_malloc(sizeof(struct imx6_eth_data));
    if (eth_data == NULL) {
        cprintf(COL_IMP, "Failed to allocate dma buffers\n");
        return NULL;
    }

    ldesc = ldesc_init(RX_DESC_COUNT, RXBUF_SIZE, TX_DESC_COUNT, TXBUF_SIZE);
    assert(ldesc);

    /* 
     * We scale up the CPU to improve benchmarking performance 
     * It is not the right place so should be moved later
     */
    arm_clk = clk_get_clock(CLK_ARM);
    clk_set_freq(arm_clk, CPU_FREQ);
    CLK_DEBUG(printf("ARM  clock frequency: %9d HZ\n", clk_get_freq(arm_clk)));

    /* initialise the eFuse controller so we can get a MAC address */
    ocotp = ocotp_init();
    /* Initialise ethernet pins */
    gpio_init();
    setup_iomux_enet();
    /* Initialise the phy library */
    miiphy_init();
    /* Initialise the phy */
    phy_micrel_init();
    /* Initialise the RGMII interface */ 
    enet = enet_init(ldesc);
    assert(enet);

    /* Fetch and set the MAC address */
    if(ocotp == NULL || ocotp_get_mac(ocotp, eth_data->ethaddr)){
        memcpy(eth_data->ethaddr, DEFAULT_MAC, 6);
    }
    enet_set_mac(enet, eth_data->ethaddr);

    /* Connect the phy to the ethernet controller */
    if(fec_init(CONFIG_FEC_MXC_PHYMASK, enet)){
        return NULL;
    }

    /* Start the controller */
    enet_enable(enet);

    /* Update book keeping */
    eth_data->irq_enabled = 0;
    eth_data->enet = enet;
    eth_data->ldesc = ldesc;
    eth_driver_set_data(&imx6_eth_driver, eth_data);
    /* done */
    return &imx6_eth_driver;
}
예제 #13
0
파일: tegra_i2c.c 프로젝트: nanakom/freebsd
static int
tegra_i2c_attach(device_t dev)
{
    int rv, rid;
    phandle_t node;
    struct tegra_i2c_softc *sc;
    uint64_t freq;

    sc = device_get_softc(dev);
    sc->dev = dev;
    node = ofw_bus_get_node(dev);

    LOCK_INIT(sc);

    /* Get the memory resource for the register mapping. */
    rid = 0;
    sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
                                         RF_ACTIVE);
    if (sc->mem_res == NULL) {
        device_printf(dev, "Cannot map registers.\n");
        rv = ENXIO;
        goto fail;
    }

    /* Allocate our IRQ resource. */
    rid = 0;
    sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
                                         RF_ACTIVE);
    if (sc->irq_res == NULL) {
        device_printf(dev, "Cannot allocate interrupt.\n");
        rv = ENXIO;
        goto fail;
    }

    /* FDT resources. */
    rv = clk_get_by_ofw_name(dev, 0, "div-clk", &sc->clk);
    if (rv != 0) {
        device_printf(dev, "Cannot get i2c clock: %d\n", rv);
        goto fail;
    }
    rv = hwreset_get_by_ofw_name(sc->dev, 0, "i2c", &sc->reset);
    if (rv != 0) {
        device_printf(sc->dev, "Cannot get i2c reset\n");
        return (ENXIO);
    }
    rv = OF_getencprop(node, "clock-frequency", &sc->bus_freq,
                       sizeof(sc->bus_freq));
    if (rv != sizeof(sc->bus_freq)) {
        sc->bus_freq = 100000;
        goto fail;
    }

    /* Request maximum frequency for I2C block 136MHz (408MHz / 3). */
    rv = clk_set_freq(sc->clk, 136000000, CLK_SET_ROUND_DOWN);
    if (rv != 0) {
        device_printf(dev, "Cannot set clock frequency\n");
        goto fail;
    }
    rv = clk_get_freq(sc->clk, &freq);
    if (rv != 0) {
        device_printf(dev, "Cannot get clock frequency\n");
        goto fail;
    }
    sc->core_freq = (uint32_t)freq;

    rv = clk_enable(sc->clk);
    if (rv != 0) {
        device_printf(dev, "Cannot enable clock: %d\n", rv);
        goto fail;
    }

    /* Init hardware. */
    rv = tegra_i2c_hw_init(sc);
    if (rv) {
        device_printf(dev, "tegra_i2c_activate failed\n");
        goto fail;
    }

    /* Setup interrupt. */
    rv = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
                        NULL, tegra_i2c_intr, sc, &sc->irq_h);
    if (rv) {
        device_printf(dev, "Cannot setup interrupt.\n");
        goto fail;
    }

    /* Attach the iicbus. */
    sc->iicbus = device_add_child(dev, "iicbus", -1);
    if (sc->iicbus == NULL) {
        device_printf(dev, "Could not allocate iicbus instance.\n");
        rv = ENXIO;
        goto fail;
    }

    /* Probe and attach the iicbus. */
    return (bus_generic_attach(dev));

fail:
    if (sc->irq_h != NULL)
        bus_teardown_intr(dev, sc->irq_res, sc->irq_h);
    if (sc->irq_res != NULL)
        bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
    if (sc->mem_res != NULL)
        bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
    LOCK_DESTROY(sc);

    return (rv);
}
예제 #14
0
static int
jz4780_timer_attach(device_t dev)
{
	struct jz4780_timer_softc *sc = device_get_softc(dev);
	pcell_t counter_freq;
	clk_t clk;

	/* There should be exactly one instance. */
	if (jz4780_timer_sc != NULL)
		return (ENXIO);

	sc->dev = dev;

	if (bus_alloc_resources(dev, jz4780_timer_spec, sc->res)) {
		device_printf(dev, "can not allocate resources for device\n");
		return (ENXIO);
	}

	counter_freq = 0;
	if (clk_get_by_name(dev, "ext", &clk) == 0) {
		uint64_t clk_freq;

		if (clk_get_freq(clk, &clk_freq) == 0)
			counter_freq = (uint32_t)clk_freq / 16;
		clk_release(clk);
	}
	if (counter_freq == 0) {
		device_printf(dev, "unable to determine ext clock frequency\n");
		/* Hardcode value we 'know' is correct */
		counter_freq = 48000000 / 16;
	}

	/*
	 * Disable the timers, select the input for each timer,
	 * clear and then start OST.
	 */

	/* Stop OST, if it happens to be running */
	CSR_WRITE_4(sc, JZ_TC_TECR, TESR_OST);
	/* Stop all other channels as well */
	CSR_WRITE_4(sc, JZ_TC_TECR, TESR_TCST0 | TESR_TCST1 | TESR_TCST2 |
	    TESR_TCST3 | TESR_TCST4 | TESR_TCST5 | TESR_TCST6 | TESR_TCST3);
	/* Clear detect mask flags */
	CSR_WRITE_4(sc, JZ_TC_TFCR, 0xFFFFFFFF);
	/* Mask all interrupts */
	CSR_WRITE_4(sc, JZ_TC_TMSR, 0xFFFFFFFF);

	/* Init counter with known data */
	CSR_WRITE_4(sc, JZ_OST_CTRL, 0);
	CSR_WRITE_4(sc, JZ_OST_CNT_LO, 0);
	CSR_WRITE_4(sc, JZ_OST_CNT_HI, 0);
	CSR_WRITE_4(sc, JZ_OST_DATA, 0xffffffff);

	/* Configure counter for external clock */
	CSR_WRITE_4(sc, JZ_OST_CTRL, OSTC_EXT_EN | OSTC_MODE | OSTC_DIV_16);

	/* Start the counter again */
	CSR_WRITE_4(sc, JZ_TC_TESR, TESR_OST);

	/* Configure TCU channel 5 similarly to OST and leave it disabled */
	CSR_WRITE_4(sc, JZ_TC_TCSR(5), TCSR_EXT_EN | TCSR_DIV_16);
	CSR_WRITE_4(sc, JZ_TC_TMCR, TMR_FMASK(5));

	if (bus_setup_intr(dev, sc->res[2], INTR_TYPE_CLK,
	    jz4780_hardclock, NULL, sc, &sc->ih_cookie)) {
		device_printf(dev, "could not setup interrupt handler\n");
		bus_release_resources(dev, jz4780_timer_spec, sc->res);
		return (ENXIO);
	}

	sc->et.et_name = "JZ4780 TCU5";
	sc->et.et_flags = ET_FLAGS_ONESHOT;
	sc->et.et_frequency = counter_freq;
	sc->et.et_quality = 1000;
	sc->et.et_min_period = (0x00000002LLU * SBT_1S) / sc->et.et_frequency;
	sc->et.et_max_period = (0x0000fffeLLU * SBT_1S) / sc->et.et_frequency;
	sc->et.et_start = jz4780_timer_start;
	sc->et.et_stop = jz4780_timer_stop;
	sc->et.et_priv = sc;

	et_register(&sc->et);

	sc->tc.tc_get_timecount = jz4780_get_timecount;
	sc->tc.tc_name = "JZ4780 OST";
	sc->tc.tc_frequency = counter_freq;
	sc->tc.tc_counter_mask = ~0u;
	sc->tc.tc_quality = 1000;
	sc->tc.tc_priv = sc;

	tc_init(&sc->tc);

	/* Now when tc is initialized, allow DELAY to find it */
	jz4780_timer_sc = sc;

	return (0);
}