示例#1
0
static int
clk_fixed_attach(device_t dev)
{
	struct clk_fixed_softc *sc;
	intptr_t clk_type;
	phandle_t node;
	struct clk_fixed_def def;
	int rv;

	sc = device_get_softc(dev);
	sc->dev = dev;
	node  = ofw_bus_get_node(dev);
	clk_type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;

	bzero(&def, sizeof(def));
	if (clk_type == CLK_TYPE_FIXED)
		rv = clk_fixed_init_fixed(sc, node, &def);
	else if (clk_type == CLK_TYPE_FIXED_FACTOR)
		rv = clk_fixed_init_fixed_factor(sc, node, &def);
	else
		rv = ENXIO;
	if (rv != 0) {
		device_printf(sc->dev, "Cannot FDT parameters.\n");
		goto fail;
	}
	rv = clk_parse_ofw_clk_name(dev, node, &def.clkdef.name);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot parse clock name.\n");
		goto fail;
	}
	sc->clkdom = clkdom_create(dev);
	KASSERT(sc->clkdom != NULL, ("Clock domain is NULL"));

	rv = clknode_fixed_register(sc->clkdom, &def);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot register fixed clock.\n");
		rv = ENXIO;
		goto fail;
	}

	rv = clkdom_finit(sc->clkdom);
	if (rv != 0) {
		device_printf(sc->dev, "Clk domain finit fails.\n");
		rv = ENXIO;
		goto fail;
	}
#ifdef CLK_DEBUG
	clkdom_dump(sc->clkdom);
#endif
	OF_prop_free(__DECONST(char *, def.clkdef.name));
	OF_prop_free(def.clkdef.parent_names);
	return (bus_generic_attach(dev));

fail:
	OF_prop_free(__DECONST(char *, def.clkdef.name));
	OF_prop_free(def.clkdef.parent_names);
	return (rv);
}
示例#2
0
static int
aw_oscclk_attach(device_t dev)
{
	struct clk_fixed_def def;
	struct clkdom *clkdom;
	phandle_t node;
	uint32_t freq;
	int error;

	node = ofw_bus_get_node(dev);

	if (OF_getencprop(node, "clock-frequency", &freq,  sizeof(freq)) <= 0) {
		device_printf(dev, "missing clock-frequency property\n");
		error = ENXIO;
		goto fail;
	}

	clkdom = clkdom_create(dev);

	memset(&def, 0, sizeof(def));
	def.clkdef.id = 1;
	def.freq = freq;
	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_fixed_register(clkdom, &def);
	if (error != 0) {
		device_printf(dev, "cannot register fixed clock\n");
		error = ENXIO;
		goto fail;
	}

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

	if (bootverbose)
		clkdom_dump(clkdom);

	free(__DECONST(char *, def.clkdef.name), M_OFWPROP);

	return (0);

fail:
	free(__DECONST(char *, def.clkdef.name), M_OFWPROP);
	return (error);
}
示例#3
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);
}
示例#4
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);
}
示例#5
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);
}
示例#6
0
int
rk_cru_attach(device_t dev)
{
	struct rk_cru_softc *sc;
	phandle_t node;
	int	i;

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

	node = ofw_bus_get_node(dev);

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

	mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);

	sc->clkdom = clkdom_create(dev);
	if (sc->clkdom == NULL)
		panic("Cannot create clkdom\n");

	for (i = 0; i < sc->nclks; i++) {
		switch (sc->clks[i].type) {
		case RK_CLK_UNDEFINED:
			break;
		case RK_CLK_PLL:
			rk_clk_pll_register(sc->clkdom, sc->clks[i].clk.pll);
			break;
		case RK_CLK_COMPOSITE:
			rk_clk_composite_register(sc->clkdom,
			    sc->clks[i].clk.composite);
			break;
		case RK_CLK_MUX:
			rk_clk_mux_register(sc->clkdom, sc->clks[i].clk.mux);
			break;
		case RK_CLK_ARMCLK:
			rk_clk_armclk_register(sc->clkdom, sc->clks[i].clk.armclk);
			break;
		default:
			device_printf(dev, "Unknown clock type\n");
			return (ENXIO);
			break;
		}
	}
	if (sc->gates)
		rk_cru_register_gates(sc);

	if (clkdom_finit(sc->clkdom) != 0)
		panic("cannot finalize clkdom initialization\n");

	if (bootverbose)
		clkdom_dump(sc->clkdom);

	clk_set_assigned(dev, node);

	/* If we have resets, register our self as a reset provider */
	if (sc->resets)
		hwreset_register_ofw_provider(dev);

	return (0);
}