1233545Sjchandra/*-
2233545Sjchandra * Copyright (c) 2003-2012 Broadcom Corporation
3233545Sjchandra * All Rights Reserved
4233545Sjchandra *
5233545Sjchandra * Redistribution and use in source and binary forms, with or without
6233545Sjchandra * modification, are permitted provided that the following conditions
7233545Sjchandra * are met:
8233545Sjchandra *
9233545Sjchandra * 1. Redistributions of source code must retain the above copyright
10233545Sjchandra *    notice, this list of conditions and the following disclaimer.
11233545Sjchandra * 2. Redistributions in binary form must reproduce the above copyright
12233545Sjchandra *    notice, this list of conditions and the following disclaimer in
13233545Sjchandra *    the documentation and/or other materials provided with the
14233545Sjchandra *    distribution.
15233545Sjchandra *
16233545Sjchandra * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
17233545Sjchandra * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18233545Sjchandra * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19233545Sjchandra * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
20233545Sjchandra * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21233545Sjchandra * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22233545Sjchandra * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23233545Sjchandra * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24233545Sjchandra * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25233545Sjchandra * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26233545Sjchandra * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27233545Sjchandra *
28233545Sjchandra * $FreeBSD: releng/10.2/sys/mips/nlm/hal/ucore_loader.h 245884 2013-01-24 15:49:47Z jchandra $
29233545Sjchandra */
30233545Sjchandra
31233545Sjchandra#ifndef __NLM_UCORE_LOADER_H__
32233545Sjchandra#define	__NLM_UCORE_LOADER_H__
33233545Sjchandra
34233545Sjchandra/**
35233545Sjchandra* @file_name ucore_loader.h
36233545Sjchandra* @author Netlogic Microsystems
37233545Sjchandra* @brief Ucore loader API header
38233545Sjchandra*/
39233545Sjchandra
40233545Sjchandra#define	CODE_SIZE_PER_UCORE	(4 << 10)
41233545Sjchandra
42233545Sjchandrastatic __inline__ void
43233545Sjchandranlm_ucore_load_image(uint64_t nae_base, int ucore)
44233545Sjchandra{
45233545Sjchandra	uint64_t addr = nae_base + NAE_UCORE_SHARED_RAM_OFFSET +
46233545Sjchandra	    (ucore * CODE_SIZE_PER_UCORE);
47233545Sjchandra	uint32_t *p = (uint32_t *)ucore_app_bin;
48233545Sjchandra	int i, size;
49233545Sjchandra
50233545Sjchandra	size = sizeof(ucore_app_bin)/sizeof(uint32_t);
51233545Sjchandra	for (i = 0; i < size; i++, addr += 4)
52245884Sjchandra		nlm_store_word_daddr(addr, htobe32(p[i]));
53233545Sjchandra
54233545Sjchandra	/* add a 'nop' if number of instructions are odd */
55233545Sjchandra	if (size & 0x1)
56233545Sjchandra		nlm_store_word_daddr(addr, 0x0);
57233545Sjchandra}
58233545Sjchandra
59233545Sjchandrastatic __inline int
60233545Sjchandranlm_ucore_write_sharedmem(uint64_t nae_base, int index, uint32_t data)
61233545Sjchandra{
62233545Sjchandra	uint32_t ucore_cfg;
63233545Sjchandra	uint64_t addr = nae_base + NAE_UCORE_SHARED_RAM_OFFSET;
64233545Sjchandra
65233545Sjchandra	if (index > 128)
66233545Sjchandra		return (-1);
67233545Sjchandra
68233545Sjchandra	ucore_cfg = nlm_read_nae_reg(nae_base, NAE_RX_UCORE_CFG);
69233545Sjchandra	/* set iram to zero */
70233545Sjchandra	nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG,
71233545Sjchandra	    (ucore_cfg & ~(0x1 << 7)));
72233545Sjchandra
73233545Sjchandra	nlm_store_word_daddr(addr + (index * 4), data);
74233545Sjchandra
75233545Sjchandra	/* restore ucore config */
76233545Sjchandra	nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG, ucore_cfg);
77233545Sjchandra	return (0);
78233545Sjchandra}
79233545Sjchandra
80233545Sjchandrastatic __inline uint32_t
81233545Sjchandranlm_ucore_read_sharedmem(uint64_t nae_base, int index)
82233545Sjchandra{
83233545Sjchandra	uint64_t addr = nae_base + NAE_UCORE_SHARED_RAM_OFFSET;
84233545Sjchandra	uint32_t ucore_cfg, val;
85233545Sjchandra
86233545Sjchandra	ucore_cfg = nlm_read_nae_reg(nae_base, NAE_RX_UCORE_CFG);
87233545Sjchandra	/* set iram to zero */
88233545Sjchandra	nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG,
89233545Sjchandra	    (ucore_cfg & ~(0x1 << 7)));
90233545Sjchandra
91233545Sjchandra	val = nlm_load_word_daddr(addr + (index * 4));
92233545Sjchandra
93233545Sjchandra	/* restore ucore config */
94233545Sjchandra	nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG, ucore_cfg);
95233545Sjchandra
96233545Sjchandra	return val;
97233545Sjchandra}
98233545Sjchandra
99233545Sjchandrastatic __inline__ int
100233545Sjchandranlm_ucore_load_all(uint64_t nae_base, uint32_t ucore_mask, int nae_reset_done)
101233545Sjchandra{
102233545Sjchandra	int i, count = 0;
103233545Sjchandra	uint32_t mask;
104233545Sjchandra	uint32_t ucore_cfg = 0;
105233545Sjchandra
106233545Sjchandra	mask = ucore_mask & 0xffff;
107233545Sjchandra
108233545Sjchandra	/* Stop all ucores */
109233545Sjchandra	if (nae_reset_done == 0) { /* Skip the Ucore reset if NAE reset is done */
110233545Sjchandra		ucore_cfg = nlm_read_nae_reg(nae_base, NAE_RX_UCORE_CFG);
111233545Sjchandra		nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG,
112233545Sjchandra		    ucore_cfg | (1 << 24));
113233545Sjchandra
114233545Sjchandra		/* poll for ucore to get in to a wait state */
115233545Sjchandra		do {
116233545Sjchandra			ucore_cfg = nlm_read_nae_reg(nae_base,
117233545Sjchandra			    NAE_RX_UCORE_CFG);
118233545Sjchandra		} while ((ucore_cfg & (1 << 25)) == 0);
119233545Sjchandra	}
120233545Sjchandra
121233545Sjchandra	for (i = 0; i < sizeof(ucore_mask) * NBBY; i++) {
122233545Sjchandra		if ((mask & (1 << i)) == 0)
123233545Sjchandra			continue;
124233545Sjchandra		nlm_ucore_load_image(nae_base, i);
125233545Sjchandra		count++;
126233545Sjchandra	}
127233545Sjchandra
128233545Sjchandra	/* Enable per-domain ucores */
129233545Sjchandra	ucore_cfg = nlm_read_nae_reg(nae_base, NAE_RX_UCORE_CFG);
130233545Sjchandra
131233545Sjchandra	/* write one to reset bits to put the ucores in reset */
132233545Sjchandra	ucore_cfg = ucore_cfg | (((mask) & 0xffff) << 8);
133233545Sjchandra	nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG, ucore_cfg);
134233545Sjchandra
135233545Sjchandra	/* write zero to reset bits to pull them out of reset */
136233545Sjchandra	ucore_cfg = ucore_cfg & (~(((mask) & 0xffff) << 8)) & ~(1 << 24);
137233545Sjchandra	nlm_write_nae_reg(nae_base, NAE_RX_UCORE_CFG, ucore_cfg);
138233545Sjchandra
139233545Sjchandra	return (count);
140233545Sjchandra}
141233545Sjchandra#endif
142