예제 #1
0
void __init ux500_timer_init(void)
{
	void __iomem *mtu_timer_base;
	void __iomem *prcmu_timer_base;
	void __iomem *tmp_base;
	struct device_node *np;

	if (cpu_is_u8500_family() || cpu_is_ux540_family()) {
		mtu_timer_base = __io_address(U8500_MTU0_BASE);
		prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
	} else {
		ux500_unknown_soc();
	}

	/* TODO: Once MTU has been DT:ed place code above into else. */
	if (of_have_populated_dt()) {
#ifdef CONFIG_OF
		np = of_find_matching_node(NULL, prcmu_timer_of_match);
		if (!np)
#endif
			goto dt_fail;

		tmp_base = of_iomap(np, 0);
		if (!tmp_base)
			goto dt_fail;

		prcmu_timer_base = tmp_base;
	}

dt_fail:
	/* Doing it the old fashioned way. */

	/*
	 * Here we register the timerblocks active in the system.
	 * Localtimers (twd) is started when both cpu is up and running.
	 * MTU register a clocksource, clockevent and sched_clock.
	 * Since the MTU is located in the VAPE power domain
	 * it will be cleared in sleep which makes it unsuitable.
	 * We however need it as a timer tick (clockevent)
	 * during boot to calibrate delay until twd is started.
	 * RTC-RTT have problems as timer tick during boot since it is
	 * depending on delay which is not yet calibrated. RTC-RTT is in the
	 * always-on powerdomain and is used as clockevent instead of twd when
	 * sleeping.
	 * The PRCMU timer 4 register a clocksource and
	 * sched_clock with higher rating then MTU since is always-on.
	 *
	 */

	nmdk_timer_init(mtu_timer_base, IRQ_MTU0);
	clksrc_dbx500_prcmu_init(prcmu_timer_base);
	ux500_twd_init();
}
예제 #2
0
파일: cache-l2x0.c 프로젝트: 01org/prd
static int __init ux500_l2x0_init(void)
{
	/* Multiplatform guard */
	if (!((cpu_is_u8500_family() || cpu_is_ux540_family())))
		return -ENODEV;

	/* Unlock before init */
	ux500_l2x0_unlock();
	outer_cache.write_sec = ux500_l2c310_write_sec;
	l2x0_of_init(0, ~0);

	return 0;
}
static int __init ux500_l2x0_init(void)
{
	u32 aux_val = 0x3e000000;

	if (cpu_is_u8500_family() || cpu_is_ux540_family())
		l2x0_base = __io_address(U8500_L2CC_BASE);
	else
		ux500_unknown_soc();

	/* Unlock before init */
	ux500_l2x0_unlock();

	/* DBx540's L2 has 128KB way size */
	if (cpu_is_ux540_family())
		/* 128KB way size */
		aux_val |= (0x4 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
	else
		/* 64KB way size */
		aux_val |= (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);

	/* 64KB way size, 8 way associativity, force WA */
	if (of_have_populated_dt())
		l2x0_of_init(aux_val, 0xc0000fff);
	else
		l2x0_init(l2x0_base, aux_val, 0xc0000fff);

	/*
	 * We can't disable l2 as we are in non secure mode, currently
	 * this seems be called only during kexec path. So let's
	 * override outer.disable with nasty assignment until we have
	 * some SMI service available.
	 */
	outer_cache.disable = NULL;

	return 0;
}
예제 #4
0
파일: cpu-db8500.c 프로젝트: 7799/linux
void __init u8500_map_io(void)
{
	/*
	 * Map the UARTs early so that the DEBUG_LL stuff continues to work.
	 */
	iotable_init(u8500_uart_io_desc, ARRAY_SIZE(u8500_uart_io_desc));

	ux500_map_io();

	iotable_init(u8500_common_io_desc, ARRAY_SIZE(u8500_common_io_desc));

	if (cpu_is_ux540_family())
		iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc));
	else
		iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
}
예제 #5
0
static int __init ux500_rtcrtt_init(void)
{
	if (cpu_is_u8500_family() || cpu_is_ux540_family()) {
		rtc_base  = __io_address(U8500_RTC_BASE);
	} else {
		pr_err("timer-rtt: Unknown DB Asic!\n");
		return -EINVAL;
	}

	if (request_irq(IRQ_DB8500_RTC, rtcrtt_interrupt,
			IRQF_SHARED | IRQF_NO_SUSPEND,
			"rtc-pl031-timer", rtc_base)) {
		pr_err("rtc-rtt: failed to register irq\n");
	}

	ux500_rtcrtt_measure_latency(false);
	return 0;
}
예제 #6
0
void ux500_add_usb(struct device *parent, resource_size_t base, int irq,
		   int *dma_rx_cfg, int *dma_tx_cfg)
{
	ux500_musb_device.resource[0].start = base;
	ux500_musb_device.resource[0].end = base + SZ_64K - 1;
	ux500_musb_device.resource[1].start = irq;
	ux500_musb_device.resource[1].end = irq;

	ux500_usb_dma_update_rx_ch_config(dma_rx_cfg);
	ux500_usb_dma_update_tx_ch_config(dma_tx_cfg);

	ux500_musb_device.dev.parent = parent;

	if (cpu_is_ux540_family())
		musb_board_data.powersave_quirks = true;


	platform_device_register(&ux500_musb_device);
}
예제 #7
0
/*
 * FIXME: Should we set up the GPIO domain here?
 *
 * The problem is that we cannot put the interrupt resources into the platform
 * device until the irqdomain has been added. Right now, we set the GIC interrupt
 * domain from init_irq(), then load the gpio driver from
 * core_initcall(nmk_gpio_init) and add the platform devices from
 * arch_initcall(customize_machine).
 *
 * This feels fragile because it depends on the gpio device getting probed
 * _before_ any device uses the gpio interrupts.
*/
void __init ux500_init_irq(void)
{
	void __iomem *dist_base;
	void __iomem *cpu_base;

	gic_arch_extn.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND;

	if (cpu_is_u8500_family() || cpu_is_ux540_family()) {
		dist_base = __io_address(U8500_GIC_DIST_BASE);
		cpu_base = __io_address(U8500_GIC_CPU_BASE);
	} else
		ux500_unknown_soc();

#ifdef CONFIG_OF
	if (of_have_populated_dt())
		irqchip_init();
	else
#endif
		gic_init(0, 29, dist_base, cpu_base);

	/*
	 * Init clocks here so that they are available for system timer
	 * initialization.
	 */
	if (cpu_is_u8500_family()) {
		prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1);
		ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1);
		u8500_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE,
			       U8500_CLKRST3_BASE, U8500_CLKRST5_BASE,
			       U8500_CLKRST6_BASE);
	} else if (cpu_is_u9540()) {
		prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1);
		ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1);
		u8500_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE,
			       U8500_CLKRST3_BASE, U8500_CLKRST5_BASE,
			       U8500_CLKRST6_BASE);
	} else if (cpu_is_u8540()) {
		prcmu_early_init(U8500_PRCMU_BASE, SZ_8K + SZ_4K - 1);
		ux500_pm_init(U8500_PRCMU_BASE, SZ_8K + SZ_4K - 1);
		u8540_clk_init();
	}
}
static int __init product_detect(void)
{
	int err;
	int origin_err;
	struct tee_operation operation = {0};
	struct tee_context context;
	struct tee_session session;

	/* Selects trustzone application needed for the job. */
	struct tee_uuid static_uuid = {
		STATIC_TEE_TA_START_LOW,
		STATIC_TEE_TA_START_MID,
		STATIC_TEE_TA_START_HIGH,
		STATIC_TEE_TA_START_CLOCKSEQ,
	};

	err = teec_initialize_context(NULL, &context);
	if (err) {
		pr_err("ux500-product: unable to initialize tee context,"
			" err = %d\n", err);
		err = -EINVAL;
		goto error0;
	}

	err = teec_open_session(&context, &session, &static_uuid,
				TEEC_LOGIN_PUBLIC, NULL, NULL, &origin_err);
	if (err) {
		pr_err("ux500-product: unable to open tee session,"
			" tee error = %d, origin error = %d\n",
			err, origin_err);
		err = -EINVAL;
		goto error1;
	}

	memset(&operation, 0, sizeof(struct tee_operation));
	if (cpu_is_u8500_family()) {
		operation.shm[0].buffer = &product_config;
		operation.shm[0].size = sizeof(product_config);
		operation.shm[0].flags = TEEC_MEM_OUTPUT;
		operation.flags = TEEC_MEMREF_0_USED;
	} else if (cpu_is_ux540_family()) {
		operation.param[0].tmpref.buffer = &product_config;
		operation.param[0].tmpref.size = sizeof(product_config);
		operation.types = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT,
						   TEEC_NONE, TEEC_NONE,
						   TEEC_NONE);
	} else {
		pr_err("ux500-product: incorrect memref\n");
		err = -EINVAL;
		goto error1;
	}

	err = teec_invoke_command(&session,
				  TEE_STA_GET_PRODUCT_CONFIG,
				  &operation, &origin_err);
	if (err) {
		pr_err("ux500-product: fetching product settings failed, err=%d",
		       err);
		err = -EINVAL;
		goto error1;
	}

	switch (product_config.product_id) {
	case TEE_PRODUCT_ID_8400:
		pr_info("ux500-product: u8400 detected\n");
		break;
	case TEE_PRODUCT_ID_8500B:
		pr_info("ux500-product: u8500B detected\n");
		break;
	case TEE_PRODUCT_ID_9500:
		pr_info("ux500-product: a9500 detected\n");
		break;
	case TEE_PRODUCT_ID_7400:
		pr_info("ux500-product: u7400 detected\n");
		break;
	case TEE_PRODUCT_ID_8500C:
		pr_info("ux500-product: u8500C detected\n");
		break;
	case TEE_PRODUCT_ID_8500A:
		pr_info("ux500-product: u8500A detected\n");
		break;
	case TEE_PRODUCT_ID_8500E:
		pr_info("ux500-product: u8500E detected\n");
		break;
	case TEE_PRODUCT_ID_8520F:
		pr_info("ux500-product: u8520F detected\n");
		break;
	case TEE_PRODUCT_ID_8520H:
		pr_info("ux500-product: u8520H detected\n");
		break;
	case TEE_PRODUCT_ID_9540:
		pr_info("ux500-product: u9540 detected\n");
		break;
	case TEE_PRODUCT_ID_9500C:
		pr_info("ux500-product: a9500C detected\n");
		break;
	case TEE_PRODUCT_ID_8500F:
		pr_info("ux500-product: u8500F detected\n");
		break;
	case TEE_PRODUCT_ID_8540APE:
		pr_info("ux500-product: u8540APE detected\n");
		break;
	case TEE_PRODUCT_ID_8540XMIP:
		pr_info("ux500-product: u8540XMIP detected\n");
		break;
	case TEE_PRODUCT_ID_8520E:
		pr_info("ux500-product: u8520E detected\n");
		break;
	case TEE_PRODUCT_ID_8520J:
		pr_info("ux500-product: u8520J detected\n");
		break;
	case TEE_PRODUCT_ID_UNKNOWN:
	default:
		pr_info("ux500-product: UNKNOWN! (0x%x) detected\n",
			product_config.product_id);
		break;
	}
	pr_info("ux500-product: JTAG is %s\n",
		ux500_jtag_enabled() ? "enabled" : "disabled");
error1:
	(void) teec_finalize_context(&context);
error0:
	return err;
}