/*
 * arch/powerpc/oprofile/op_model_7450.c
 *
 * Freescale 745x/744x oprofile support, based on fsl_booke support
 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
 *
 * Copyright (c) 2004 Freescale Semiconductor, Inc
 *
 * Author: Andy Fleming
 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/oprofile.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/processor.h>
#include <asm/cputable.h>
#include <asm/page.h>
#include <asm/pmc.h>
#include <asm/oprofile_impl.h>

static unsigned long reset_value[OP_MAX_COUNTER];

static int oprofile_running;
static u32 mmcr0_val, mmcr1_val, mmcr2_val;

#define MMCR0_PMC1_SHIFT	6
#define MMCR0_PMC2_SHIFT	0
#define MMCR1_PMC3_SHIFT	27
#define MMCR1_PMC4_SHIFT	22
#define MMCR1_PMC5_SHIFT	17
#define MMCR1_PMC6_SHIFT	11

#define mmcr0_event1(event) \
	((event << MMCR0_PMC1_SHIFT) & MMCR0_PMC1SEL)
#define mmcr0_event2(event) \
	((event << MMCR0_PMC2_SHIFT) & MMCR0_PMC2SEL)

#define mmcr1_event3(event) \
	((event << MMCR1_PMC3_SHIFT) & MMCR1_PMC3SEL)
#define mmcr1_event4(event) \
	((event << MMCR1_PMC4_SHIFT) & MMCR1_PMC4SEL)
#define mmcr1_event5(event) \
	((event << MMCR1_PMC5_SHIFT) & MMCR1_PMC5SEL)
#define mmcr1_event6(event) \
	((event << MMCR1_PMC6_SHIFT) & MMCR1_PMC6SEL)

#define MMCR0_INIT (MMCR0_FC | MMCR0_FCS | MMCR0_FCP | MMCR0_FCM1 | MMCR0_FCM0)

/* Unfreezes the counters on this CPU, enables the interrupt,
 * enables the counters to trigger the interrupt, and sets the
 * counters to only count when the mark bit is not set.
 */
static void pmc_start_ctrs(void)
{
	u32 mmcr0 = mfspr(SPRN_MMCR0);

	mmcr0 &= ~(MMCR0_FC | MMCR0_FCM0);
	mmcr0 |= (MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE);

	mtspr(SPRN_MMCR0, mmcr0);
}

/* Disables the counters on this CPU, and freezes them */
static void pmc_stop_ctrs(void)
{
	u32 mmcr0 = mfspr(SPRN_MMCR0);

	mmcr0 |= MMCR0_FC;
	mmcr0 &= ~(MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE);

	mtspr(SPRN_MMCR0, mmcr0);
}

/* Configures the counters on this CPU based on the global
 * settings */
static void fsl7450_cpu_setup(struct op_counter_config *ctr)
{
	/* freeze all counters */
	pmc_stop_ctrs();

	mtspr(SPRN_MMCR0, mmcr0_val);
	mtspr(SPRN_MMCR1, mmcr1_val);
	mtspr(SPRN_MMCR2, mmcr2_val);
}

#define NUM_CTRS 6

/* Configures the global settings for the countes on all CPUs. */
static void fsl7450_reg_setup(struct op_counter_config *ctr,
			     struct op_system_config *sys,
			     int num_ctrs)
{
	int i;

	/* Our counters count up, and "count" refers to
	 * how much before the next interrupt, and we interrupt
	 * on overflow.  So we calculate the starting value
	 * which will give us "count" until overflow.
	 * Then we set the events on the enabled counters */
	for (i = 0; i < NUM_CTRS; ++i)
		reset_value[i] = 0x80000000UL - ctr[i].count;

	/* Set events for Counters 1 & 2 */
	mmcr0_val = MMCR0_INIT | mmcr0_event1(ctr[0].event)
		| mmcr0_event2(ctr[1].event);

	/* Setup user/kernel bits */
	if (sys->enable_kernel)
		mmcr0_val &= ~(MMCR0_FCS);

	if (sys->enable_user)
		mmcr0_val &= ~(MMCR0_FCP);

	/* Set events for Counters 3-6 */
	mmcr1_val = mmcr1_event3(ctr[2].event)
		| mmcr1_event4(ctr[3].event)
		| mmcr1_event5(ctr[4].event)
		| mmcr1_event6(ctr[5].event);

	mmcr2_val = 0;
}

/* Sets the counters on this CPU to the chosen values, and starts them */
static void fsl7450_start(struct op_counter_config *ctr)
{
	int i;

	mtmsr(mfmsr() | MSR_PMM);

	for (i = 0; i < NUM_CTRS; ++i) {
		if (ctr[i].enabled)
			classic_ctr_write(i, reset_value[i]);
		else
			classic_ctr_write(i, 0);
	}

	/* Clear the freeze bit, and enable the interrupt.
	 * The counters won't actually start until the rfi clears
	 * the PMM bit */
	pmc_start_ctrs();

	oprofile_running = 1;
}

/* Stop the counters on this CPU */
static void fsl7450_stop(void)
{
	/* freeze counters */
	pmc_stop_ctrs();

	oprofile_running = 0;

	mb();
}


/* Handle the interrupt on this CPU, and log a sample for each
 * event that triggered the interrupt */
static void fsl7450_handle_interrupt(struct pt_regs *regs,
				    struct op_counter_config *ctr)
{
	unsigned long pc;
	int is_kernel;
	int val;
	int i;

	/* set the PMM bit (see comment below) */
	mtmsr(mfmsr() | MSR_PMM);

	pc = mfspr(SPRN_SIAR);
	is_kernel = is_kernel_addr(pc);

	for (i = 0; i < NUM_CTRS; ++i) {
		val = classic_ctr_read(i);
		if (val < 0) {
			if (oprofile_running && ctr[i].enabled) {
				oprofile_add_ext_sample(pc, regs, i, is_kernel);
				classic_ctr_write(i, reset_value[i]);
			} else {
				classic_ctr_write(i, 0);
			}
		}
	}

	/* The freeze bit was set by the interrupt. */
	/* Clear the freeze bit, and reenable the interrupt.
	 * The counters won't actually start until the rfi clears
	 * the PMM bit */
	pmc_start_ctrs();
}

struct op_powerpc_model op_model_7450= {
	.reg_setup		= fsl7450_reg_setup,
	.cpu_setup		= fsl7450_cpu_setup,
	.start			= fsl7450_start,
	.stop			= fsl7450_stop,
	.handle_interrupt	= fsl7450_handle_interrupt,
};
