uboot/arch/powerpc/cpu/mpc85xx/liodn.c
<<
>>
Prefs
   1/*
   2 * Copyright 2008-2011 Freescale Semiconductor, Inc.
   3 *
   4 * See file CREDITS for list of people who contributed to this
   5 * project.
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 of
  10 * the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 * MA 02111-1307 USA
  21 */
  22
  23#include <common.h>
  24#include <libfdt.h>
  25#include <fdt_support.h>
  26
  27#include <asm/immap_85xx.h>
  28#include <asm/io.h>
  29#include <asm/processor.h>
  30#include <asm/fsl_portals.h>
  31#include <asm/fsl_liodn.h>
  32
  33int get_dpaa_liodn(enum fsl_dpaa_dev dpaa_dev, u32 *liodns, int liodn_offset)
  34{
  35        liodns[0] = liodn_bases[dpaa_dev].id[0] + liodn_offset;
  36
  37        if (liodn_bases[dpaa_dev].num_ids == 2)
  38                liodns[1] = liodn_bases[dpaa_dev].id[1] + liodn_offset;
  39
  40        return liodn_bases[dpaa_dev].num_ids;
  41}
  42
  43static void set_srio_liodn(struct srio_liodn_id_table *tbl, int size)
  44{
  45        int i;
  46
  47        for (i = 0; i < size; i++) {
  48                unsigned long reg_off = tbl[i].reg_offset[0];
  49                out_be32((u32 *)reg_off, tbl[i].id[0]);
  50
  51                if (tbl[i].num_ids == 2) {
  52                        reg_off = tbl[i].reg_offset[1];
  53                        out_be32((u32 *)reg_off, tbl[i].id[1]);
  54                }
  55        }
  56}
  57
  58static void set_liodn(struct liodn_id_table *tbl, int size)
  59{
  60        int i;
  61
  62        for (i = 0; i < size; i++) {
  63                u32 liodn;
  64                if (tbl[i].num_ids == 2) {
  65                        liodn = (tbl[i].id[0] << 16) | tbl[i].id[1];
  66                } else {
  67                        liodn = tbl[i].id[0];
  68                }
  69
  70                out_be32((volatile u32 *)(tbl[i].reg_offset), liodn);
  71        }
  72}
  73
  74static void setup_sec_liodn_base(void)
  75{
  76        ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
  77        u32 base;
  78
  79        if (!IS_E_PROCESSOR(get_svr()))
  80                return;
  81
  82        /* QILCR[QSLOM] */
  83        out_be32(&sec->qilcr_ms, 0x3ff<<16);
  84
  85        base = (liodn_bases[FSL_HW_PORTAL_SEC].id[0] << 16) |
  86                liodn_bases[FSL_HW_PORTAL_SEC].id[1];
  87
  88        out_be32(&sec->qilcr_ls, base);
  89}
  90
  91#ifdef CONFIG_SYS_DPAA_FMAN
  92static void setup_fman_liodn_base(enum fsl_dpaa_dev dev,
  93                                  struct liodn_id_table *tbl, int size)
  94{
  95        int i;
  96        ccsr_fman_t *fm;
  97        u32 base;
  98
  99        switch(dev) {
 100        case FSL_HW_PORTAL_FMAN1:
 101                fm = (void *)CONFIG_SYS_FSL_FM1_ADDR;
 102                break;
 103
 104#if (CONFIG_SYS_NUM_FMAN == 2)
 105        case FSL_HW_PORTAL_FMAN2:
 106                fm = (void *)CONFIG_SYS_FSL_FM2_ADDR;
 107                break;
 108#endif
 109        default:
 110                printf("Error: Invalid device type to %s\n", __FUNCTION__);
 111                return ;
 112        }
 113
 114        base = (liodn_bases[dev].id[0] << 16) | liodn_bases[dev].id[0];
 115
 116        /* setup all bases the same */
 117        for (i = 0; i < 32; i++) {
 118                out_be32(&fm->fm_dma.fmdmplr[i], base);
 119        }
 120
 121        /* update tbl to ... */
 122        for (i = 0; i < size; i++)
 123                tbl[i].id[0] += liodn_bases[dev].id[0];
 124}
 125#endif
 126
 127static void setup_pme_liodn_base(void)
 128{
 129#ifdef CONFIG_SYS_DPAA_PME
 130        ccsr_pme_t *pme = (void *)CONFIG_SYS_FSL_CORENET_PME_ADDR;
 131        u32 base = (liodn_bases[FSL_HW_PORTAL_PME].id[0] << 16) |
 132                        liodn_bases[FSL_HW_PORTAL_PME].id[1];
 133
 134        out_be32(&pme->liodnbr, base);
 135#endif
 136}
 137
 138#ifdef CONFIG_SYS_FSL_RAID_ENGINE
 139static void setup_raide_liodn_base(void)
 140{
 141        struct ccsr_raide *raide = (void *)CONFIG_SYS_FSL_RAID_ENGINE_ADDR;
 142
 143        /* setup raid engine liodn base for data/desc ; both set to 47 */
 144        u32 base = (liodn_bases[FSL_HW_PORTAL_RAID_ENGINE].id[0] << 16) |
 145                        liodn_bases[FSL_HW_PORTAL_RAID_ENGINE].id[0];
 146
 147        out_be32(&raide->liodnbr, base);
 148}
 149#endif
 150
 151#ifdef CONFIG_SYS_DPAA_RMAN
 152static void set_rman_liodn(struct liodn_id_table *tbl, int size)
 153{
 154        int i;
 155        struct ccsr_rman *rman = (void *)CONFIG_SYS_FSL_CORENET_RMAN_ADDR;
 156
 157        for (i = 0; i < size; i++) {
 158                /* write the RMan block number */
 159                out_be32(&rman->mmitar, i);
 160                /* write the liodn offset corresponding to the block */
 161                out_be32((u32 *)(tbl[i].reg_offset), tbl[i].id[0]);
 162        }
 163}
 164
 165static void setup_rman_liodn_base(struct liodn_id_table *tbl, int size)
 166{
 167        int i;
 168        struct ccsr_rman *rman = (void *)CONFIG_SYS_FSL_CORENET_RMAN_ADDR;
 169        u32 base = liodn_bases[FSL_HW_PORTAL_RMAN].id[0];
 170
 171        out_be32(&rman->mmliodnbr, base);
 172
 173        /* update liodn offset */
 174        for (i = 0; i < size; i++)
 175                tbl[i].id[0] += base;
 176}
 177#endif
 178
 179void set_liodns(void)
 180{
 181        /* setup general liodn offsets */
 182        set_liodn(liodn_tbl, liodn_tbl_sz);
 183
 184        /* setup SRIO port liodns */
 185        set_srio_liodn(srio_liodn_tbl, srio_liodn_tbl_sz);
 186
 187        /* setup SEC block liodn bases & offsets if we have one */
 188        if (IS_E_PROCESSOR(get_svr())) {
 189                set_liodn(sec_liodn_tbl, sec_liodn_tbl_sz);
 190                setup_sec_liodn_base();
 191        }
 192
 193        /* setup FMAN block(s) liodn bases & offsets if we have one */
 194#ifdef CONFIG_SYS_DPAA_FMAN
 195        set_liodn(fman1_liodn_tbl, fman1_liodn_tbl_sz);
 196        setup_fman_liodn_base(FSL_HW_PORTAL_FMAN1, fman1_liodn_tbl,
 197                                fman1_liodn_tbl_sz);
 198
 199#if (CONFIG_SYS_NUM_FMAN == 2)
 200        set_liodn(fman2_liodn_tbl, fman2_liodn_tbl_sz);
 201        setup_fman_liodn_base(FSL_HW_PORTAL_FMAN2, fman2_liodn_tbl,
 202                                fman2_liodn_tbl_sz);
 203#endif
 204#endif
 205        /* setup PME liodn base */
 206        setup_pme_liodn_base();
 207
 208#ifdef CONFIG_SYS_FSL_RAID_ENGINE
 209        /* raid engine ccr addr code for liodn */
 210        set_liodn(raide_liodn_tbl, raide_liodn_tbl_sz);
 211        setup_raide_liodn_base();
 212#endif
 213
 214#ifdef CONFIG_SYS_DPAA_RMAN
 215        /* setup RMan liodn offsets */
 216        set_rman_liodn(rman_liodn_tbl, rman_liodn_tbl_sz);
 217        /* setup RMan liodn base */
 218        setup_rman_liodn_base(rman_liodn_tbl, rman_liodn_tbl_sz);
 219#endif
 220}
 221
 222static void fdt_fixup_srio_liodn(void *blob, struct srio_liodn_id_table *tbl)
 223{
 224        int i, srio_off;
 225
 226        /* search for srio node, if doesn't exist just return - nothing todo */
 227        srio_off = fdt_node_offset_by_compatible(blob, -1, "fsl,srio");
 228        if (srio_off < 0)
 229                return ;
 230
 231        for (i = 0; i < srio_liodn_tbl_sz; i++) {
 232                int off, portid = tbl[i].portid;
 233
 234                off = fdt_node_offset_by_prop_value(blob, srio_off,
 235                         "cell-index", &portid, 4);
 236                if (off >= 0) {
 237                        off = fdt_setprop(blob, off, "fsl,liodn",
 238                                &tbl[i].id[0],
 239                                sizeof(u32) * tbl[i].num_ids);
 240                        if (off > 0)
 241                                printf("WARNING unable to set fsl,liodn for "
 242                                        "fsl,srio port %d: %s\n",
 243                                        portid, fdt_strerror(off));
 244                } else {
 245                        debug("WARNING: couldn't set fsl,liodn for srio: %s.\n",
 246                                fdt_strerror(off));
 247                }
 248        }
 249}
 250
 251static void fdt_fixup_liodn_tbl(void *blob, struct liodn_id_table *tbl, int sz)
 252{
 253        int i;
 254
 255        for (i = 0; i < sz; i++) {
 256                int off;
 257
 258                if (tbl[i].compat == NULL)
 259                        continue;
 260
 261                off = fdt_node_offset_by_compat_reg(blob,
 262                                tbl[i].compat, tbl[i].compat_offset);
 263                if (off >= 0) {
 264                        off = fdt_setprop(blob, off, "fsl,liodn",
 265                                &tbl[i].id[0],
 266                                sizeof(u32) * tbl[i].num_ids);
 267                        if (off > 0)
 268                                printf("WARNING unable to set fsl,liodn for "
 269                                        "%s: %s\n",
 270                                        tbl[i].compat, fdt_strerror(off));
 271                } else {
 272                        debug("WARNING: could not set fsl,liodn for %s: %s.\n",
 273                                        tbl[i].compat, fdt_strerror(off));
 274                }
 275        }
 276}
 277
 278void fdt_fixup_liodn(void *blob)
 279{
 280        fdt_fixup_srio_liodn(blob, srio_liodn_tbl);
 281
 282        fdt_fixup_liodn_tbl(blob, liodn_tbl, liodn_tbl_sz);
 283#ifdef CONFIG_SYS_DPAA_FMAN
 284        fdt_fixup_liodn_tbl(blob, fman1_liodn_tbl, fman1_liodn_tbl_sz);
 285#if (CONFIG_SYS_NUM_FMAN == 2)
 286        fdt_fixup_liodn_tbl(blob, fman2_liodn_tbl, fman2_liodn_tbl_sz);
 287#endif
 288#endif
 289        fdt_fixup_liodn_tbl(blob, sec_liodn_tbl, sec_liodn_tbl_sz);
 290
 291#ifdef CONFIG_SYS_FSL_RAID_ENGINE
 292        fdt_fixup_liodn_tbl(blob, raide_liodn_tbl, raide_liodn_tbl_sz);
 293#endif
 294
 295#ifdef CONFIG_SYS_DPAA_RMAN
 296        fdt_fixup_liodn_tbl(blob, rman_liodn_tbl, rman_liodn_tbl_sz);
 297#endif
 298}
 299