msm: kgsl: add power tracepoints

Add kgsl_clk, kgsl_bus, kgsl_irq, kgsl_rail, kgsl_pwrlevel,
kgsl_pwr_set_state and kgsl_pwr_request_state trace
events.

Change-Id: I3bf246f350b1208123ab9a33c08495cea9c533eb
Signed-off-by: Jeremy Gebben <jgebben@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index b301743..f82b038 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -318,4 +318,6 @@
 		irqreturn_t (*dev_isr) (int, void*));
 void kgsl_device_platform_remove(struct kgsl_device *device);
 
+const char *kgsl_pwrstate_to_str(unsigned int state);
+
 #endif  /* __KGSL_DEVICE_H */
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 89b4df1..f4abf99 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -18,6 +18,7 @@
 #include "kgsl.h"
 #include "kgsl_pwrscale.h"
 #include "kgsl_device.h"
+#include "kgsl_trace.h"
 
 #define KGSL_PWRFLAGS_POWER_ON 0
 #define KGSL_PWRFLAGS_CLK_ON   1
@@ -62,24 +63,20 @@
 	if (new_level < (pwr->num_pwrlevels - 1) &&
 		new_level >= pwr->thermal_pwrlevel &&
 		new_level != pwr->active_pwrlevel) {
+		struct kgsl_pwrlevel *pwrlevel = &pwr->pwrlevels[new_level];
 		pwr->active_pwrlevel = new_level;
 		if ((test_bit(KGSL_PWRFLAGS_CLK_ON, &pwr->power_flags)) ||
 			(device->state == KGSL_STATE_NAP))
-			clk_set_rate(pwr->grp_clks[0],
-					pwr->pwrlevels[pwr->active_pwrlevel].
-					gpu_freq);
+			clk_set_rate(pwr->grp_clks[0], pwrlevel->gpu_freq);
 		if (test_bit(KGSL_PWRFLAGS_AXI_ON, &pwr->power_flags)) {
 			if (pwr->pcl)
 				msm_bus_scale_client_update_request(pwr->pcl,
-					pwr->pwrlevels[pwr->active_pwrlevel].
-					bus_freq);
+					pwrlevel->bus_freq);
 			else if (pwr->ebi1_clk)
-				clk_set_rate(pwr->ebi1_clk,
-					pwr->pwrlevels[pwr->active_pwrlevel].
-					bus_freq);
+				clk_set_rate(pwr->ebi1_clk, pwrlevel->bus_freq);
 		}
-		KGSL_PWR_WARN(device, "kgsl pwr level changed to %d\n",
-					  pwr->active_pwrlevel);
+		trace_kgsl_pwrlevel(device, pwr->active_pwrlevel,
+				    pwrlevel->gpu_freq);
 	}
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_pwrlevel_change);
@@ -335,8 +332,7 @@
 	if (state == KGSL_PWRFLAGS_OFF) {
 		if (test_and_clear_bit(KGSL_PWRFLAGS_CLK_ON,
 			&pwr->power_flags)) {
-			KGSL_PWR_INFO(device,
-				"clocks off, device %d\n", device->id);
+			trace_kgsl_clk(device, state);
 			for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
 				if (pwr->grp_clks[i])
 					clk_disable(pwr->grp_clks[i]);
@@ -350,9 +346,7 @@
 	} else if (state == KGSL_PWRFLAGS_ON) {
 		if (!test_and_set_bit(KGSL_PWRFLAGS_CLK_ON,
 			&pwr->power_flags)) {
-			KGSL_PWR_INFO(device,
-				"clocks on, device %d\n", device->id);
-
+			trace_kgsl_clk(device, state);
 			if ((pwr->pwrlevels[0].gpu_freq > 0) &&
 				(device->state != KGSL_STATE_NAP))
 				clk_set_rate(pwr->grp_clks[0],
@@ -376,8 +370,7 @@
 	if (state == KGSL_PWRFLAGS_OFF) {
 		if (test_and_clear_bit(KGSL_PWRFLAGS_AXI_ON,
 			&pwr->power_flags)) {
-			KGSL_PWR_INFO(device,
-				"axi off, device %d\n", device->id);
+			trace_kgsl_bus(device, state);
 			if (pwr->ebi1_clk) {
 				clk_set_rate(pwr->ebi1_clk, 0);
 				clk_disable(pwr->ebi1_clk);
@@ -389,8 +382,7 @@
 	} else if (state == KGSL_PWRFLAGS_ON) {
 		if (!test_and_set_bit(KGSL_PWRFLAGS_AXI_ON,
 			&pwr->power_flags)) {
-			KGSL_PWR_INFO(device,
-				"axi on, device %d\n", device->id);
+			trace_kgsl_bus(device, state);
 			if (pwr->ebi1_clk) {
 				clk_enable(pwr->ebi1_clk);
 				clk_set_rate(pwr->ebi1_clk,
@@ -412,16 +404,14 @@
 	if (state == KGSL_PWRFLAGS_OFF) {
 		if (test_and_clear_bit(KGSL_PWRFLAGS_POWER_ON,
 			&pwr->power_flags)) {
-			KGSL_PWR_INFO(device,
-				"power off, device %d\n", device->id);
+			trace_kgsl_rail(device, state);
 			if (pwr->gpu_reg)
 				regulator_disable(pwr->gpu_reg);
 		}
 	} else if (state == KGSL_PWRFLAGS_ON) {
 		if (!test_and_set_bit(KGSL_PWRFLAGS_POWER_ON,
 			&pwr->power_flags)) {
-			KGSL_PWR_INFO(device,
-				"power on, device %d\n", device->id);
+			trace_kgsl_rail(device, state);
 			if (pwr->gpu_reg)
 				regulator_enable(pwr->gpu_reg);
 		}
@@ -435,16 +425,14 @@
 	if (state == KGSL_PWRFLAGS_ON) {
 		if (!test_and_set_bit(KGSL_PWRFLAGS_IRQ_ON,
 			&pwr->power_flags)) {
-			KGSL_PWR_INFO(device,
-				"irq on, device %d\n", device->id);
+			trace_kgsl_irq(device, state);
 			enable_irq(pwr->interrupt_num);
 			device->ftbl->irqctrl(device, 1);
 		}
 	} else if (state == KGSL_PWRFLAGS_OFF) {
 		if (test_and_clear_bit(KGSL_PWRFLAGS_IRQ_ON,
 			&pwr->power_flags)) {
-			KGSL_PWR_INFO(device,
-				"irq off, device %d\n", device->id);
+			trace_kgsl_irq(device, state);
 			device->ftbl->irqctrl(device, 0);
 			if (in_interrupt())
 				disable_irq_nosync(pwr->interrupt_num);
@@ -727,8 +715,8 @@
 	case KGSL_STATE_SLUMBER:
 		break;
 	default:
-		KGSL_PWR_WARN(device, "unhandled state %x\n",
-				device->state);
+		KGSL_PWR_WARN(device, "unhandled state %s\n",
+				kgsl_pwrstate_to_str(device->state));
 		break;
 	}
 	return 0;
@@ -760,8 +748,8 @@
 	case KGSL_STATE_SLUMBER:
 		break;
 	default:
-		KGSL_PWR_WARN(device, "unhandled state %x\n",
-				device->state);
+		KGSL_PWR_WARN(device, "unhandled state %s\n",
+				kgsl_pwrstate_to_str(device->state));
 		break;
 	}
 	return 0;
@@ -837,8 +825,8 @@
 	case KGSL_STATE_ACTIVE:
 		break;
 	default:
-		KGSL_PWR_WARN(device, "unhandled state %x\n",
-				device->state);
+		KGSL_PWR_WARN(device, "unhandled state %s\n",
+				kgsl_pwrstate_to_str(device->state));
 		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 		break;
 	}
@@ -865,7 +853,7 @@
 
 void kgsl_pwrctrl_set_state(struct kgsl_device *device, unsigned int state)
 {
-	KGSL_PWR_WARN(device, "%x\n", state);
+	trace_kgsl_pwr_set_state(device, state);
 	device->state = state;
 	device->requested_state = KGSL_STATE_NONE;
 }
@@ -874,7 +862,36 @@
 void kgsl_pwrctrl_request_state(struct kgsl_device *device, unsigned int state)
 {
 	if (state != KGSL_STATE_NONE && state != device->requested_state)
-		KGSL_PWR_INFO(device, "%x\n", state);
+		trace_kgsl_pwr_request_state(device, state);
 	device->requested_state = state;
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_request_state);
+
+const char *kgsl_pwrstate_to_str(unsigned int state)
+{
+	switch (state) {
+	case KGSL_STATE_NONE:
+		return "NONE";
+	case KGSL_STATE_INIT:
+		return "INIT";
+	case KGSL_STATE_ACTIVE:
+		return "ACTIVE";
+	case KGSL_STATE_NAP:
+		return "NAP";
+	case KGSL_STATE_SLEEP:
+		return "SLEEP";
+	case KGSL_STATE_SUSPEND:
+		return "SUSPEND";
+	case KGSL_STATE_HUNG:
+		return "HUNG";
+	case KGSL_STATE_DUMP_AND_RECOVER:
+		return "DNR";
+	case KGSL_STATE_SLUMBER:
+		return "SLUMBER";
+	default:
+		break;
+	}
+	return "UNKNOWN";
+}
+EXPORT_SYMBOL(kgsl_pwrstate_to_str);
+
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index 7c14ac1..86a9adc 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -155,6 +155,108 @@
 		__entry->result
 	)
 );
+
+DECLARE_EVENT_CLASS(kgsl_pwr_template,
+	TP_PROTO(struct kgsl_device *device, int on),
+
+	TP_ARGS(device, on),
+
+	TP_STRUCT__entry(
+		__string(device_name, device->name)
+		__field(int, on)
+	),
+
+	TP_fast_assign(
+		__assign_str(device_name, device->name);
+		__entry->on = on;
+	),
+
+	TP_printk(
+		"d_name=%s %s",
+		__get_str(device_name),
+		__entry->on ? "on" : "off"
+	)
+);
+
+DEFINE_EVENT(kgsl_pwr_template, kgsl_clk,
+	TP_PROTO(struct kgsl_device *device, int on),
+	TP_ARGS(device, on)
+);
+
+DEFINE_EVENT(kgsl_pwr_template, kgsl_irq,
+	TP_PROTO(struct kgsl_device *device, int on),
+	TP_ARGS(device, on)
+);
+
+DEFINE_EVENT(kgsl_pwr_template, kgsl_bus,
+	TP_PROTO(struct kgsl_device *device, int on),
+	TP_ARGS(device, on)
+);
+
+DEFINE_EVENT(kgsl_pwr_template, kgsl_rail,
+	TP_PROTO(struct kgsl_device *device, int on),
+	TP_ARGS(device, on)
+);
+
+TRACE_EVENT(kgsl_pwrlevel,
+
+	TP_PROTO(struct kgsl_device *device, unsigned int pwrlevel,
+		 unsigned int freq),
+
+	TP_ARGS(device, pwrlevel, freq),
+
+	TP_STRUCT__entry(
+		__string(device_name, device->name)
+		__field(unsigned int, pwrlevel)
+		__field(unsigned int, freq)
+	),
+
+	TP_fast_assign(
+		__assign_str(device_name, device->name);
+		__entry->pwrlevel = pwrlevel;
+		__entry->freq = freq;
+	),
+
+	TP_printk(
+		"d_name=%s pwrlevel=%d freq=%d",
+		__get_str(device_name),
+		__entry->pwrlevel,
+		__entry->freq
+	)
+);
+
+DECLARE_EVENT_CLASS(kgsl_pwrstate_template,
+	TP_PROTO(struct kgsl_device *device, unsigned int state),
+
+	TP_ARGS(device, state),
+
+	TP_STRUCT__entry(
+		__string(device_name, device->name)
+		__field(unsigned int, state)
+	),
+
+	TP_fast_assign(
+		__assign_str(device_name, device->name);
+		__entry->state = state;
+	),
+
+	TP_printk(
+		"d_name=%s %s",
+		__get_str(device_name),
+		kgsl_pwrstate_to_str(__entry->state)
+	)
+);
+
+DEFINE_EVENT(kgsl_pwrstate_template, kgsl_pwr_set_state,
+	TP_PROTO(struct kgsl_device *device, unsigned int state),
+	TP_ARGS(device, state)
+);
+
+DEFINE_EVENT(kgsl_pwrstate_template, kgsl_pwr_request_state,
+	TP_PROTO(struct kgsl_device *device, unsigned int state),
+	TP_ARGS(device, state)
+);
+
 #endif /* _KGSL_TRACE_H */
 
 /* This part must be outside protection */