1/* 2 * OMAP2 ARM Performance Monitoring Unit (PMU) Support 3 * 4 * Copyright (C) 2012 Texas Instruments, Inc. 5 * 6 * Contacts: 7 * Jon Hunter <jon-hunter@ti.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 */ 14#include <linux/of.h> 15 16#include <asm/system_info.h> 17 18#include "soc.h" 19#include "omap_hwmod.h" 20#include "omap_device.h" 21 22static char *omap2_pmu_oh_names[] = {"mpu"}; 23static char *omap3_pmu_oh_names[] = {"mpu", "debugss"}; 24static char *omap4430_pmu_oh_names[] = {"l3_main_3", "l3_instr", "debugss"}; 25static struct platform_device *omap_pmu_dev; 26 27/** 28 * omap2_init_pmu - creates and registers PMU platform device 29 * @oh_num: Number of OMAP HWMODs required to create PMU device 30 * @oh_names: Array of OMAP HWMODS names required to create PMU device 31 * 32 * Uses OMAP HWMOD framework to create and register an ARM PMU device 33 * from a list of HWMOD names passed. Currently supports OMAP2, OMAP3 34 * and OMAP4 devices. 35 */ 36static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[]) 37{ 38 int i; 39 struct omap_hwmod *oh[3]; 40 char *dev_name = cpu_architecture() == CPU_ARCH_ARMv6 ? 41 "armv6-pmu" : "armv7-pmu"; 42 43 if ((!oh_num) || (oh_num > 3)) 44 return -EINVAL; 45 46 for (i = 0; i < oh_num; i++) { 47 oh[i] = omap_hwmod_lookup(oh_names[i]); 48 if (!oh[i]) { 49 pr_err("Could not look up %s hwmod\n", oh_names[i]); 50 return -ENODEV; 51 } 52 } 53 54 omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0); 55 WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n", 56 dev_name); 57 58 return PTR_RET(omap_pmu_dev); 59} 60 61static int __init omap_init_pmu(void) 62{ 63 unsigned oh_num; 64 char **oh_names; 65 66 /* XXX Remove this check when the CTI driver is available */ 67 if (cpu_is_omap443x()) { 68 pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n"); 69 return 0; 70 } 71 72 if (of_have_populated_dt()) 73 return 0; 74 75 /* 76 * To create an ARM-PMU device the following HWMODs 77 * are required for the various OMAP2+ devices. 78 * 79 * OMAP24xx: mpu 80 * OMAP3xxx: mpu, debugss 81 * OMAP4430: l3_main_3, l3_instr, debugss 82 * OMAP4460/70: mpu, debugss 83 */ 84 if (cpu_is_omap443x()) { 85 oh_num = ARRAY_SIZE(omap4430_pmu_oh_names); 86 oh_names = omap4430_pmu_oh_names; 87 } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 88 oh_num = ARRAY_SIZE(omap3_pmu_oh_names); 89 oh_names = omap3_pmu_oh_names; 90 } else { 91 oh_num = ARRAY_SIZE(omap2_pmu_oh_names); 92 oh_names = omap2_pmu_oh_names; 93 } 94 95 return omap2_init_pmu(oh_num, oh_names); 96} 97omap_subsys_initcall(omap_init_pmu); 98