/* * Copyright (c) 2012 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * * EXYNOS - PPMU support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include "exynos_ppmu.h" #define PPMU_PMNC 0x4 #define PPMU_CNTENS 0x8 #define PPMU_CNT_AUTO 0x30 #define PPMU_PMCNT0_HIGH 0x004C #define PPMU_PMCNT1_HIGH 0x0050 #define PPMU_PMCNT2_HIGH 0x0054 #define PPMU_PMCNT3_HIGH 0x0044 #define PPMU_CCNT_HIGH 0x0058 #define PPMU_PMCNT0_LOW 0x0034 #define PPMU_PMCNT1_LOW 0x0038 #define PPMU_PMCNT2_LOW 0x003C #define PPMU_PMCNT3_LOW 0x0040 #define PPMU_CCNT_LOW 0x0048 #define PPMU_CH_EV0_TYPE 0x200 #define PPMU_CH_EV1_TYPE 0x204 #define PPMU_CH_EV2_TYPE 0x208 #define PPMU_CH_EV3_TYPE 0x20c #define PPMU_SM_ID_V 0x220 #define PPMU_SM_ID_A 0x224 #define EVENT_RD_ACTIVATED 0x0 #define EVENT_WR_ACTIVATED 0x1 #define EVENT_RD_DATA 0x4 #define EVENT3_RD_DATA 0x4 #define EVENT3_WR_DATA 0x5 #define EVENT3_RW_DATA 0x22 /* 0x1: disable Q channel */ /* auto mode */ #define BIT_REGVALUE ((0x1<<24) | (0x1<<20)) #define BIT_CH_CCNT (0x1<<31) #define BIT_CH_PMCNT0 (0x1<<0) #define BIT_CH_PMCNT1 (0x1<<1) #define BIT_CH_PMCNT2 (0x1<<2) #define BIT_CH_PMCNT3 (0x1<<3) #define BIT_CH_ALL (BIT_CH_CCNT | BIT_CH_PMCNT0 | \ BIT_CH_PMCNT1 | BIT_CH_PMCNT2 | \ BIT_CH_PMCNT3) void exynos_read_ppmu(struct ppmu_data *ppmu, void __iomem *ppmu_base, u32 channel) { if (!channel) channel = BIT_CH_ALL; if (channel & BIT_CH_CCNT) ppmu->ccnt = __raw_readl(ppmu_base + PPMU_CCNT_LOW); if (channel & BIT_CH_PMCNT0) ppmu->pmcnt0 = __raw_readl(ppmu_base + PPMU_PMCNT0_LOW); if (channel & BIT_CH_PMCNT1) ppmu->pmcnt1 = __raw_readl(ppmu_base + PPMU_PMCNT1_LOW); if (channel & BIT_CH_PMCNT2) ppmu->pmcnt2 = __raw_readl(ppmu_base + PPMU_PMCNT2_LOW); if (channel & BIT_CH_PMCNT3) ppmu->pmcnt3 = __raw_readl(ppmu_base + PPMU_PMCNT3_LOW); } void exynos_init_ppmu(void __iomem *ppmu_base, u32 mask_v, u32 mask_a) { __raw_writel(BIT_REGVALUE | 0x6, ppmu_base + PPMU_PMNC); /* Count Enable CCNT, PMCNTTx */ __raw_writel(BIT_CH_ALL, ppmu_base + PPMU_CNTENS); __raw_writel(EVENT_RD_ACTIVATED, ppmu_base + PPMU_CH_EV0_TYPE); __raw_writel(EVENT_WR_ACTIVATED, ppmu_base + PPMU_CH_EV1_TYPE); __raw_writel(EVENT_RD_DATA, ppmu_base + PPMU_CH_EV2_TYPE); __raw_writel(EVENT3_WR_DATA, ppmu_base + PPMU_CH_EV3_TYPE); if (mask_v) { __raw_writel(mask_v, ppmu_base + PPMU_SM_ID_V); __raw_writel(mask_a, ppmu_base + PPMU_SM_ID_A); } } void exynos_reset_ppmu(void __iomem *ppmu_base, u32 channel) { if (!channel) channel = BIT_CH_ALL; __raw_writel(channel, ppmu_base + PPMU_CNT_AUTO); } void exynos_start_ppmu(void __iomem *ppmu_base) { __raw_writel(BIT_REGVALUE | 0x1, ppmu_base + PPMU_PMNC); } void exynos_stop_ppmu(void __iomem *ppmu_base) { __raw_writel(BIT_REGVALUE, ppmu_base + PPMU_PMNC); } void exynos_exit_ppmu(void __iomem *ppmu_base) { __raw_writel(BIT_REGVALUE, ppmu_base + PPMU_PMNC); }