/*
 * Copyright (C) 2012-2014, 2016 ARM Limited. All rights reserved.
 * 
 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
 * 
 * A copy of the licence is included with the program, and can also be obtained from Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "mali_broadcast.h"
#include "mali_kernel_common.h"
#include "mali_osk.h"

#define MALI_BROADCAST_REGISTER_SIZE      0x1000
#define MALI_BROADCAST_REG_BROADCAST_MASK    0x0
#define MALI_BROADCAST_REG_INTERRUPT_MASK    0x4

struct mali_bcast_unit {
	struct mali_hw_core hw_core;
	u32 current_mask;
};

struct mali_bcast_unit *mali_bcast_unit_create(const _mali_osk_resource_t *resource)
{
	struct mali_bcast_unit *bcast_unit = NULL;

	MALI_DEBUG_ASSERT_POINTER(resource);
	MALI_DEBUG_PRINT(2, ("Broadcast: Creating Mali Broadcast unit: %s\n",
			     resource->description));

	bcast_unit = _mali_osk_malloc(sizeof(struct mali_bcast_unit));
	if (NULL == bcast_unit) {
		MALI_PRINT_ERROR(("Broadcast: Failed to allocate memory for Broadcast unit\n"));
		return NULL;
	}

	if (_MALI_OSK_ERR_OK == mali_hw_core_create(&bcast_unit->hw_core,
			resource, MALI_BROADCAST_REGISTER_SIZE)) {
		bcast_unit->current_mask = 0;
		mali_bcast_reset(bcast_unit);

		return bcast_unit;
	} else {
		MALI_PRINT_ERROR(("Broadcast: Failed map broadcast unit\n"));
	}

	_mali_osk_free(bcast_unit);

	return NULL;
}

void mali_bcast_unit_delete(struct mali_bcast_unit *bcast_unit)
{
	MALI_DEBUG_ASSERT_POINTER(bcast_unit);
	mali_hw_core_delete(&bcast_unit->hw_core);
	_mali_osk_free(bcast_unit);
}

/* Call this function to add the @group's id into bcast mask
 * Note: redundant calling this function with same @group
 * doesn't make any difference as calling it once
 */
void mali_bcast_add_group(struct mali_bcast_unit *bcast_unit,
			  struct mali_group *group)
{
	u32 bcast_id;
	u32 broadcast_mask;

	MALI_DEBUG_ASSERT_POINTER(bcast_unit);
	MALI_DEBUG_ASSERT_POINTER(group);

	bcast_id = mali_pp_core_get_bcast_id(mali_group_get_pp_core(group));

	broadcast_mask = bcast_unit->current_mask;

	broadcast_mask |= (bcast_id); /* add PP core to broadcast */
	broadcast_mask |= (bcast_id << 16); /* add MMU to broadcast */

	/* store mask so we can restore on reset */
	bcast_unit->current_mask = broadcast_mask;
}

/* Call this function to remove @group's id from bcast mask
 * Note: redundant calling this function with same @group
 * doesn't make any difference as calling it once
 */
void mali_bcast_remove_group(struct mali_bcast_unit *bcast_unit,
			     struct mali_group *group)
{
	u32 bcast_id;
	u32 broadcast_mask;

	MALI_DEBUG_ASSERT_POINTER(bcast_unit);
	MALI_DEBUG_ASSERT_POINTER(group);

	bcast_id = mali_pp_core_get_bcast_id(mali_group_get_pp_core(group));

	broadcast_mask = bcast_unit->current_mask;

	broadcast_mask &= ~((bcast_id << 16) | bcast_id);

	/* store mask so we can restore on reset */
	bcast_unit->current_mask = broadcast_mask;
}

void mali_bcast_reset(struct mali_bcast_unit *bcast_unit)
{
	MALI_DEBUG_ASSERT_POINTER(bcast_unit);

	MALI_DEBUG_PRINT(4,
			 ("Broadcast: setting mask 0x%08X + 0x%08X (reset)\n",
			  bcast_unit->current_mask,
			  bcast_unit->current_mask & 0xFF));

	/* set broadcast mask */
	mali_hw_core_register_write(&bcast_unit->hw_core,
				    MALI_BROADCAST_REG_BROADCAST_MASK,
				    bcast_unit->current_mask);

	/* set IRQ override mask */
	mali_hw_core_register_write(&bcast_unit->hw_core,
				    MALI_BROADCAST_REG_INTERRUPT_MASK,
				    bcast_unit->current_mask & 0xFF);
}

void mali_bcast_disable(struct mali_bcast_unit *bcast_unit)
{
	MALI_DEBUG_ASSERT_POINTER(bcast_unit);

	MALI_DEBUG_PRINT(4, ("Broadcast: setting mask 0x0 + 0x0 (disable)\n"));

	/* set broadcast mask */
	mali_hw_core_register_write(&bcast_unit->hw_core,
				    MALI_BROADCAST_REG_BROADCAST_MASK,
				    0x0);

	/* set IRQ override mask */
	mali_hw_core_register_write(&bcast_unit->hw_core,
				    MALI_BROADCAST_REG_INTERRUPT_MASK,
				    0x0);
}
