Пример #1
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);
}
Пример #2
0
static int
awusbphy_init(device_t dev)
{
    struct awusbphy_softc *sc;
    phandle_t node;
    char pname[20];
    int error, off;
    regulator_t reg;
    hwreset_t rst;
    clk_t clk;

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

    /* Enable clocks */
    for (off = 0; clk_get_by_ofw_index(dev, off, &clk) == 0; off++) {
        error = clk_enable(clk);
        if (error != 0) {
            device_printf(dev, "couldn't enable clock %s\n",
                          clk_get_name(clk));
            return (error);
        }
    }

    /* De-assert resets */
    for (off = 0; hwreset_get_by_ofw_idx(dev, off, &rst) == 0; off++) {
        error = hwreset_deassert(rst);
        if (error != 0) {
            device_printf(dev, "couldn't de-assert reset %d\n",
                          off);
            return (error);
        }
    }

    /* Get regulators */
    for (off = 0; off < USBPHY_NPHYS; off++) {
        snprintf(pname, sizeof(pname), "usb%d_vbus-supply", off);
        if (regulator_get_by_ofw_property(dev, pname, &reg) == 0)
            sc->reg[off] = reg;
    }

    /* Get GPIOs */
    error = gpio_pin_get_by_ofw_property(dev, node, "usb0_id_det-gpios",
                                         &sc->id_det_pin);
    if (error == 0)
        sc->id_det_valid = 1;
    error = gpio_pin_get_by_ofw_property(dev, node, "usb0_vbus_det-gpios",
                                         &sc->vbus_det_pin);
    if (error == 0)
        sc->vbus_det_valid = 1;

    return (0);
}
Пример #3
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));
}
Пример #4
0
static int
a10_twsi_attach(device_t dev)
{
	struct twsi_softc *sc;
	clk_t clk;
	hwreset_t rst;
	int error;

	sc = device_get_softc(dev);

	/* De-assert reset */
	if (hwreset_get_by_ofw_idx(dev, 0, &rst) == 0) {
		error = hwreset_deassert(rst);
		if (error != 0) {
			device_printf(dev, "could not de-assert reset\n");
			return (error);
		}
	}

	/* Activate clock */
	error = clk_get_by_ofw_index(dev, 0, &clk);
	if (error != 0) {
		device_printf(dev, "could not find clock\n");
		return (error);
	}
	error = clk_enable(clk);
	if (error != 0) {
		device_printf(dev, "could not enable clock\n");
		return (error);
	}

	sc->reg_data = TWI_DATA;
	sc->reg_slave_addr = TWI_ADDR;
	sc->reg_slave_ext_addr = TWI_XADDR;
	sc->reg_control = TWI_CNTR;
	sc->reg_status = TWI_STAT;
	sc->reg_baud_rate = TWI_CCR;
	sc->reg_soft_reset = TWI_SRST;

	/* Setup baud rate params */
	sc->baud_rate[IIC_SLOW].param = TWSI_BAUD_RATE_PARAM(11, 2);
	sc->baud_rate[IIC_FAST].param = TWSI_BAUD_RATE_PARAM(11, 2);
	sc->baud_rate[IIC_FASTEST].param = TWSI_BAUD_RATE_PARAM(2, 2);

	return (twsi_attach(dev));
}
Пример #5
0
static int
awusbphy_init(device_t dev)
{
	char pname[20];
	int error, off;
	regulator_t reg;
	hwreset_t rst;
	clk_t clk;

	/* Enable clocks */
	for (off = 0; clk_get_by_ofw_index(dev, off, &clk) == 0; off++) {
		error = clk_enable(clk);
		if (error != 0) {
			device_printf(dev, "couldn't enable clock %s\n",
			    clk_get_name(clk));
			return (error);
		}
	}

	/* De-assert resets */
	for (off = 0; hwreset_get_by_ofw_idx(dev, off, &rst) == 0; off++) {
		error = hwreset_deassert(rst);
		if (error != 0) {
			device_printf(dev, "couldn't de-assert reset %d\n",
			    off);
			return (error);
		}
	}

	/* Enable regulator(s) */
	for (off = 0; off < USBPHY_NUMOFF; off++) {
		snprintf(pname, sizeof(pname), "usb%d_vbus-supply", off);
		if (regulator_get_by_ofw_property(dev, pname, &reg) != 0)
			continue;
		error = regulator_enable(reg);
		if (error != 0) {
			device_printf(dev, "couldn't enable regulator %s\n",
			    pname);
			return (error);
		}
	}

	return (0);
}
Пример #6
0
static int
clk_fixed_init_fixed_factor(struct clk_fixed_softc *sc, phandle_t node,
    struct clk_fixed_def *def)
{
	int rv;
	clk_t  parent;

	def->clkdef.id = 1;
	rv = OF_getencprop(node, "clock-mult", &def->mult,  sizeof(def->mult));
	if (rv <= 0)
		return (ENXIO);
	rv = OF_getencprop(node, "clock-div", &def->div,  sizeof(def->div));
	if (rv <= 0)
		return (ENXIO);
	/* Get name of parent clock */
	rv = clk_get_by_ofw_index(sc->dev, 0, &parent);
	if (rv != 0)
		return (ENXIO);
	def->clkdef.parent_names = malloc(sizeof(char *), M_OFWPROP, M_WAITOK);
	def->clkdef.parent_names[0] = clk_get_name(parent);
	def->clkdef.parent_cnt  = 1;
	clk_release(parent);
	return (0);
}
Пример #7
0
static int
aw_usbclk_attach(device_t dev)
{
	struct aw_usbclk_softc *sc;
	struct clkdom *clkdom;
	const char **names;
	const char *pname;
	int index, nout, error;
	enum aw_usbclk_type type;
	uint32_t *indices;
	clk_t clk_parent, clk_parent_pll;
	bus_size_t psize;
	phandle_t node;

	sc = device_get_softc(dev);
	node = ofw_bus_get_node(dev);
	indices = NULL;
	type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;

	if (ofw_reg_to_paddr(node, 0, &sc->reg, &psize, NULL) != 0) {
		device_printf(dev, "cannot parse 'reg' property\n");
		return (ENXIO);
	}

	clkdom = clkdom_create(dev);

	nout = clk_parse_ofw_out_names(dev, node, &names, &indices);
	if (nout == 0) {
		device_printf(dev, "no clock outputs found\n");
		error = ENOENT;
		goto fail;
	}

	if (indices == NULL && type == AW_A10_USBCLK)
		indices = aw_usbclk_indices_a10;
	else if (indices == NULL && type == AW_H3_USBCLK)
		indices = aw_usbclk_indices_h3;

	error = clk_get_by_ofw_index(dev, 0, &clk_parent);
	if (error != 0) {
		device_printf(dev, "cannot parse clock parent\n");
		return (ENXIO);
	}
	if (type == AW_A83T_USBCLK) {
		error = clk_get_by_ofw_index(dev, 1, &clk_parent_pll);
		if (error != 0) {
			device_printf(dev, "cannot parse pll clock parent\n");
			return (ENXIO);
		}
	}

	for (index = 0; index < nout; index++) {
		if (strcmp(names[index], "usb_hsic_pll") == 0)
			pname = clk_get_name(clk_parent_pll);
		else
			pname = clk_get_name(clk_parent);
		error = aw_usbclk_create(dev, sc->reg, clkdom, pname,
		    names[index], indices != NULL ? indices[index] : index);
		if (error)
			goto fail;
	}

	if (clkdom_finit(clkdom) != 0) {
		device_printf(dev, "cannot finalize clkdom initialization\n");
		error = ENXIO;
		goto fail;
	}

	if (bootverbose)
		clkdom_dump(clkdom);

	hwreset_register_ofw_provider(dev);

	return (0);

fail:
	return (error);
}
Пример #8
0
static int
a10dmac_attach(device_t dev)
{
	struct a10dmac_softc *sc;
	unsigned int index;
	clk_t clk;
	int error;

	sc = device_get_softc(dev);

	if (bus_alloc_resources(dev, a10dmac_spec, sc->sc_res)) {
		device_printf(dev, "cannot allocate resources for device\n");
		return (ENXIO);
	}

	mtx_init(&sc->sc_mtx, "a10 dmac", NULL, MTX_SPIN);

	/* Activate DMA controller clock */
	error = clk_get_by_ofw_index(dev, 0, 0, &clk);
	if (error != 0) {
		device_printf(dev, "cannot get clock\n");
		return (error);
	}
	error = clk_enable(clk);
	if (error != 0) {
		device_printf(dev, "cannot enable clock\n");
		return (error);
	}

	/* Disable all interrupts and clear pending status */
	DMA_WRITE(sc, AWIN_DMA_IRQ_EN_REG, 0);
	DMA_WRITE(sc, AWIN_DMA_IRQ_PEND_STA_REG, ~0);

	/* Initialize channels */
	for (index = 0; index < NDMA_CHANNELS; index++) {
		sc->sc_ndma_channels[index].ch_sc = sc;
		sc->sc_ndma_channels[index].ch_index = index;
		sc->sc_ndma_channels[index].ch_type = CH_NDMA;
		sc->sc_ndma_channels[index].ch_callback = NULL;
		sc->sc_ndma_channels[index].ch_callbackarg = NULL;
		sc->sc_ndma_channels[index].ch_regoff = AWIN_NDMA_REG(index);
		DMACH_WRITE(&sc->sc_ndma_channels[index], AWIN_NDMA_CTL_REG, 0);
	}
	for (index = 0; index < DDMA_CHANNELS; index++) {
		sc->sc_ddma_channels[index].ch_sc = sc;
		sc->sc_ddma_channels[index].ch_index = index;
		sc->sc_ddma_channels[index].ch_type = CH_DDMA;
		sc->sc_ddma_channels[index].ch_callback = NULL;
		sc->sc_ddma_channels[index].ch_callbackarg = NULL;
		sc->sc_ddma_channels[index].ch_regoff = AWIN_DDMA_REG(index);
		DMACH_WRITE(&sc->sc_ddma_channels[index], AWIN_DDMA_CTL_REG, 0);
	}

	error = bus_setup_intr(dev, sc->sc_res[1], INTR_MPSAFE | INTR_TYPE_MISC,
	    NULL, a10dmac_intr, sc, &sc->sc_ih);
	if (error != 0) {
		device_printf(dev, "could not setup interrupt handler\n");
		bus_release_resources(dev, a10dmac_spec, sc->sc_res);
		mtx_destroy(&sc->sc_mtx);
		return (ENXIO);
	}

	OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev);
	return (0);
}
Пример #9
0
static int
tegra_rtc_attach(device_t dev)
{
	int rv, rid;
	struct tegra_rtc_softc *sc;

	sc = device_get_softc(dev);
	sc->dev = 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;
	}

	/* OFW resources. */
	rv = clk_get_by_ofw_index(dev, 0, 0, &sc->clk);
	if (rv != 0) {
		device_printf(dev, "Cannot get i2c clock: %d\n", rv);
		goto fail;
	}
	rv = clk_enable(sc->clk);
	if (rv != 0) {
		device_printf(dev, "Cannot enable clock: %d\n", rv);
		goto fail;
	}

	/* Init hardware. */
	WR4(sc, RTC_SECONDS_ALARM0, 0);
	WR4(sc, RTC_SECONDS_ALARM1, 0);
	WR4(sc, RTC_INTR_STATUS, 0xFFFFFFFF);
	WR4(sc, RTC_INTR_MASK, 0);

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

	/*
	 * Register as a time of day clock with 1-second resolution.
	 *
	 * XXXX Not yet, we don't have support for multiple RTCs
	 */
	/* clock_register(dev, 1000000); */

	return (bus_generic_attach(dev));

fail:
	if (sc->clk != NULL)
		clk_release(sc->clk);
	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);
}
Пример #10
0
static int
aw_cpuclk_attach(device_t dev)
{
	struct clk_mux_def def;
	struct clkdom *clkdom;
	bus_addr_t paddr;
	bus_size_t psize;
	phandle_t node;
	int error, ncells, i;
	clk_t clk;

	node = ofw_bus_get_node(dev);

	if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) {
		device_printf(dev, "cannot parse 'reg' property\n");
		return (ENXIO);
	}

	error = ofw_bus_parse_xref_list_get_length(node, "clocks",
	    "#clock-cells", &ncells);
	if (error != 0) {
		device_printf(dev, "cannot get clock count\n");
		return (error);
	}

	clkdom = clkdom_create(dev);

	memset(&def, 0, sizeof(def));
	def.clkdef.id = 1;
	def.clkdef.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP,
	    M_WAITOK);
	for (i = 0; i < ncells; i++) {
		error = clk_get_by_ofw_index(dev, 0, i, &clk);
		if (error != 0) {
			device_printf(dev, "cannot get clock %d\n", i);
			goto fail;
		}
		def.clkdef.parent_names[i] = clk_get_name(clk);
		clk_release(clk);
	}
	def.clkdef.parent_cnt = ncells;
	def.offset = paddr;
	def.shift = CPU_CLK_SRC_SEL_SHIFT;
	def.width = CPU_CLK_SRC_SEL_WIDTH;

	error = clk_parse_ofw_clk_name(dev, node, &def.clkdef.name);
	if (error != 0) {
		device_printf(dev, "cannot parse clock name\n");
		error = ENXIO;
		goto fail;
	}

	error = clknode_mux_register(clkdom, &def);
	if (error != 0) {
		device_printf(dev, "cannot register mux clock\n");
		error = ENXIO;
		goto fail;
	}

	if (clkdom_finit(clkdom) != 0) {
		device_printf(dev, "cannot finalize clkdom initialization\n");
		error = ENXIO;
		goto fail;
	}

	OF_prop_free(__DECONST(char *, def.clkdef.parent_names));
	OF_prop_free(__DECONST(char *, def.clkdef.name));

	if (bootverbose)
		clkdom_dump(clkdom);

	return (0);

fail:
	OF_prop_free(__DECONST(char *, def.clkdef.name));
	return (error);
}
Пример #11
0
static int
aw_gate_attach(device_t dev)
{
	struct clkdom *clkdom;
	const char **names;
	int index, nout, error;
	uint32_t *indices;
	clk_t clk_parent;
	bus_addr_t paddr;
	bus_size_t psize;
	phandle_t node;

	node = ofw_bus_get_node(dev);
	indices = NULL;

	if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) {
		device_printf(dev, "cannot parse 'reg' property\n");
		return (ENXIO);
	}

	clkdom = clkdom_create(dev);

	nout = clk_parse_ofw_out_names(dev, node, &names, &indices);
	if (nout == 0) {
		device_printf(dev, "no clock outputs found\n");
		error = ENOENT;
		goto fail;
	}
	if (indices == NULL) {
		device_printf(dev, "no clock-indices property\n");
		error = ENXIO;
		goto fail;
	}

	error = clk_get_by_ofw_index(dev, 0, &clk_parent);
	if (error != 0) {
		device_printf(dev, "cannot parse clock parent\n");
		return (ENXIO);
	}

	for (index = 0; index < nout; index++) {
		error = aw_gate_create(dev, paddr, clkdom,
		    clk_get_name(clk_parent), names[index], indices[index]);
		if (error)
			goto fail;
	}

	if (clkdom_finit(clkdom) != 0) {
		device_printf(dev, "cannot finalize clkdom initialization\n");
		error = ENXIO;
		goto fail;
	}

	if (bootverbose)
		clkdom_dump(clkdom);

	return (0);

fail:
	return (error);
}