コード例 #1
0
static void
exyo_attach(device_t parent, device_t self, void *aux)
{
	const struct exyo_locators *l = NULL;
	struct exyo_softc * const sc = &exyo_sc;
	prop_dictionary_t dict = device_properties(self);
	size_t nl = 0;

	sc->sc_dev = self;
	sc->sc_bst = &exynos_bs_tag;
	sc->sc_a4x_bst = &exynos_a4x_bs_tag;
	sc->sc_bsh = exynos_core_bsh;
	sc->sc_dmat = &exynos_bus_dma_tag;
	sc->sc_coherent_dmat = &exynos_coherent_bus_dma_tag;

	const uint16_t product_id = EXYNOS_PRODUCT_ID(exynos_soc_id);
	aprint_naive(": Exynos %x\n", product_id);
	aprint_normal(": Exynos %x\n", product_id);

	/* add sysctl nodes */
	exynos_sysctl_cpufreq_init();

	/* add all children */
#if defined(EXYNOS4)
	if (IS_EXYNOS4_P()) {
		l = exynos4_locinfo.locators;
		nl = exynos4_locinfo.nlocators;
	}
#endif
#if defined(EXYNOS5)
	if (IS_EXYNOS5_P()) {
		l = exynos5_locinfo.locators;
		nl = exynos5_locinfo.nlocators;
	}	
#endif 
	KASSERT(l != NULL);
	KASSERT(nl > 0);

	for (const struct exyo_locators *loc = l; loc < l + nl; loc++) {
		char prop_name[31];
		bool skip;

		if (loc->loc_port == EXYOCF_PORT_DEFAULT) {
			snprintf(prop_name, sizeof(prop_name),
			    "no-%s", loc->loc_name);
		} else {
			snprintf(prop_name, sizeof(prop_name),
			    "no-%s-%d", loc->loc_name, loc->loc_port);
		}
		if (prop_dictionary_get_bool(dict, prop_name, &skip) && skip)
			continue;

		struct exyo_attach_args exyo = {
			.exyo_loc = *loc,
			.exyo_core_bst = sc->sc_bst,
			.exyo_core_a4x_bst = sc->sc_a4x_bst,
			.exyo_core_bsh = sc->sc_bsh,
			.exyo_dmat = sc->sc_dmat,
			.exyo_coherent_dmat = sc->sc_coherent_dmat,
		};
		cfdata_t cf = config_search_ia(exyo_find,
		    sc->sc_dev, "exyo", &exyo);
		if (cf == NULL) {
#ifdef EXYO_REQUIRED
			if (loc->loc_flags & EXYO_REQUIRED)
				panic("%s: failed to find %s!", __func__,
				    loc->loc_name);
#endif
			if (loc->loc_port == EXYOCF_PORT_DEFAULT) {
				aprint_verbose_dev(self, "%s not found\n",
				    loc->loc_name);
			} else {
				aprint_verbose_dev(self, "%s%d not found\n",
				    loc->loc_name, loc->loc_port);
			}
			continue;
		}
		config_attach(sc->sc_dev, cf, &exyo, exyo_print);
	}
}
コード例 #2
0
ファイル: exynos_soc.c プロジェクト: ryo/netbsd-src
void
exynos_device_register(device_t self, void *aux)
{
	if (device_is_a(self, "armperiph")
	    && device_is_a(device_parent(self), "mainbus")) {
		/*
		 * XXX KLUDGE ALERT XXX
		 * The iot mainbus supplies is completely wrong since it scales
		 * addresses by 2.  The simplest remedy is to replace with our
		 * bus space used for the armcore registers (which armperiph uses).
		 */
		struct mainbus_attach_args * const mb = aux;
		mb->mb_iot = &armv7_generic_bs_tag;
		return;
	}
	if (device_is_a(self, "armgic")
	    && device_is_a(device_parent(self), "armperiph")) {
		/*
		 * The Exynos4420 armgic is located at a different location!
		 */

		extern uint32_t exynos_soc_id;

		switch (EXYNOS_PRODUCT_ID(exynos_soc_id)) {
#ifdef EXYNOS5
		case 0xe5410:
			/* offsets not changed on matt's request */
#if 0
			mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE;
			mpcaa->mpcaa_off1 = EXYNOS5_GIC_IOP_DISTRIBUTOR_OFFSET;
			mpcaa->mpcaa_off2 = EXYNOS5_GIC_IOP_CONTROLLER_OFFSET;
#endif
			break;
		case 0xe5422: {
			struct mpcore_attach_args * const mpcaa = aux;

			mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE;
			mpcaa->mpcaa_off1 = EXYNOS5_GIC_IOP_DISTRIBUTOR_OFFSET;
			mpcaa->mpcaa_off2 = EXYNOS5_GIC_IOP_CONTROLLER_OFFSET;
			break;
		}
#endif
#ifdef EXYNOS4
		case 0xe4410:
		case 0xe4412: {
			struct mpcore_attach_args * const mpcaa = aux;

			mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE;
			mpcaa->mpcaa_off1 = EXYNOS4_GIC_DISTRIBUTOR_OFFSET;
			mpcaa->mpcaa_off2 = EXYNOS4_GIC_CNTR_OFFSET;
			break;
		      }
#endif
		default:
			panic("%s: unknown SoC product id %#x", __func__,
			    (u_int)EXYNOS_PRODUCT_ID(exynos_soc_id));
		}
		return;
	}
	if (device_is_a(self, "armgtmr") || device_is_a(self, "mct")) {
#ifdef EXYNOS5
		/*
		 * The global timer is dependent on the MCT running.
		 */
		bus_size_t o = EXYNOS5_MCT_OFFSET + MCT_G_TCON;
		uint32_t v = bus_space_read_4(&armv7_generic_bs_tag, exynos_core_bsh,
		     o);
		v |= G_TCON_START;
		bus_space_write_4(&armv7_generic_bs_tag, exynos_core_bsh, o, v);
#endif
		/*
		 * The frequencies of the timers are the reference
		 * frequency.
		 */
		prop_dictionary_set_uint32(device_properties(self),
		    "frequency", EXYNOS_F_IN_FREQ);
		return;
	}
}