uboot/arch/arm/cpu/armv7/tegra2/funcmux.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2011 The Chromium OS Authors.
   3 * See file CREDITS for list of people who contributed to this
   4 * project.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation; either version 2 of
   9 * the License, or (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  19 * MA 02111-1307 USA
  20 */
  21
  22/* Tegra2 high-level function multiplexing */
  23#include <common.h>
  24#include <asm/arch/clock.h>
  25#include <asm/arch/funcmux.h>
  26#include <asm/arch/pinmux.h>
  27
  28int funcmux_select(enum periph_id id, int config)
  29{
  30        int bad_config = config != FUNCMUX_DEFAULT;
  31
  32        switch (id) {
  33        case PERIPH_ID_UART1:
  34                if (config == FUNCMUX_UART1_IRRX_IRTX) {
  35                        pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA);
  36                        pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA);
  37                        pinmux_tristate_disable(PINGRP_IRRX);
  38                        pinmux_tristate_disable(PINGRP_IRTX);
  39                        /*
  40                         * Tegra appears to boot with function UARTA pre-
  41                         * selected on mux group SDB. If two mux groups are
  42                         * both set to the same function, it's unclear which
  43                         * group's pins drive the RX signals into the HW.
  44                         * For UARTA, SDB certainly overrides group IRTX in
  45                         * practice. To solve this, configure some alternative
  46                         * function on SDB to avoid the conflict. Also, tri-
  47                         * state the group to avoid driving any signal onto it
  48                         * until we know what's connected.
  49                         */
  50                        pinmux_tristate_enable(PINGRP_SDB);
  51                        pinmux_set_func(PINGRP_SDB,  PMUX_FUNC_SDIO3);
  52                }
  53                break;
  54
  55        case PERIPH_ID_UART2:
  56                if (config == FUNCMUX_UART2_IRDA) {
  57                        pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA);
  58                        pinmux_tristate_disable(PINGRP_UAD);
  59                }
  60                break;
  61
  62        case PERIPH_ID_UART4:
  63                if (config == FUNCMUX_UART4_GMC) {
  64                        pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD);
  65                        pinmux_tristate_disable(PINGRP_GMC);
  66                }
  67                break;
  68
  69        case PERIPH_ID_DVC_I2C:
  70                /* there is only one selection, pinmux_config is ignored */
  71                if (config == FUNCMUX_DVC_I2CP) {
  72                        pinmux_set_func(PINGRP_I2CP, PMUX_FUNC_I2C);
  73                        pinmux_tristate_disable(PINGRP_I2CP);
  74                }
  75                break;
  76
  77        case PERIPH_ID_I2C1:
  78                /* support pinmux_config of 0 for now, */
  79                if (config == FUNCMUX_I2C1_RM) {
  80                        pinmux_set_func(PINGRP_RM, PMUX_FUNC_I2C);
  81                        pinmux_tristate_disable(PINGRP_RM);
  82                }
  83                break;
  84        case PERIPH_ID_I2C2: /* I2C2 */
  85                switch (config) {
  86                case FUNCMUX_I2C2_DDC:  /* DDC pin group, select I2C2 */
  87                        pinmux_set_func(PINGRP_DDC, PMUX_FUNC_I2C2);
  88                        /* PTA to HDMI */
  89                        pinmux_set_func(PINGRP_PTA, PMUX_FUNC_HDMI);
  90                        pinmux_tristate_disable(PINGRP_DDC);
  91                        break;
  92                case FUNCMUX_I2C2_PTA:  /* PTA pin group, select I2C2 */
  93                        pinmux_set_func(PINGRP_PTA, PMUX_FUNC_I2C2);
  94                        /* set DDC_SEL to RSVDx (RSVD2 works for now) */
  95                        pinmux_set_func(PINGRP_DDC, PMUX_FUNC_RSVD2);
  96                        pinmux_tristate_disable(PINGRP_PTA);
  97                        bad_config = 0;
  98                        break;
  99                }
 100                break;
 101        case PERIPH_ID_I2C3: /* I2C3 */
 102                /* support pinmux_config of 0 for now */
 103                if (config == FUNCMUX_I2C3_DTF) {
 104                        pinmux_set_func(PINGRP_DTF, PMUX_FUNC_I2C3);
 105                        pinmux_tristate_disable(PINGRP_DTF);
 106                }
 107                break;
 108
 109        case PERIPH_ID_SDMMC2:
 110                if (config == FUNCMUX_SDMMC2_DTA_DTD_8BIT) {
 111                        pinmux_set_func(PINGRP_DTA, PMUX_FUNC_SDIO2);
 112                        pinmux_set_func(PINGRP_DTD, PMUX_FUNC_SDIO2);
 113
 114                        pinmux_tristate_disable(PINGRP_DTA);
 115                        pinmux_tristate_disable(PINGRP_DTD);
 116                }
 117                break;
 118
 119        case PERIPH_ID_SDMMC3:
 120                switch (config) {
 121                case FUNCMUX_SDMMC3_SDB_SLXA_8BIT:
 122                        pinmux_set_func(PINGRP_SLXA, PMUX_FUNC_SDIO3);
 123                        pinmux_set_func(PINGRP_SLXC, PMUX_FUNC_SDIO3);
 124                        pinmux_set_func(PINGRP_SLXD, PMUX_FUNC_SDIO3);
 125                        pinmux_set_func(PINGRP_SLXK, PMUX_FUNC_SDIO3);
 126
 127                        pinmux_tristate_disable(PINGRP_SLXA);
 128                        pinmux_tristate_disable(PINGRP_SLXC);
 129                        pinmux_tristate_disable(PINGRP_SLXD);
 130                        pinmux_tristate_disable(PINGRP_SLXK);
 131                        /* fall through */
 132
 133                case FUNCMUX_SDMMC3_SDB_4BIT:
 134                        pinmux_set_func(PINGRP_SDB, PMUX_FUNC_SDIO3);
 135                        pinmux_set_func(PINGRP_SDC, PMUX_FUNC_SDIO3);
 136                        pinmux_set_func(PINGRP_SDD, PMUX_FUNC_SDIO3);
 137
 138                        pinmux_tristate_disable(PINGRP_SDB);
 139                        pinmux_tristate_disable(PINGRP_SDC);
 140                        pinmux_tristate_disable(PINGRP_SDD);
 141                        bad_config = 0;
 142                        break;
 143                }
 144                break;
 145
 146        case PERIPH_ID_SDMMC4:
 147                switch (config) {
 148                case FUNCMUX_SDMMC4_ATC_ATD_8BIT:
 149                        pinmux_set_func(PINGRP_ATC, PMUX_FUNC_SDIO4);
 150                        pinmux_set_func(PINGRP_ATD, PMUX_FUNC_SDIO4);
 151
 152                        pinmux_tristate_disable(PINGRP_ATC);
 153                        pinmux_tristate_disable(PINGRP_ATD);
 154                        break;
 155
 156                case FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT:
 157                        pinmux_set_func(PINGRP_GME, PMUX_FUNC_SDIO4);
 158                        pinmux_tristate_disable(PINGRP_GME);
 159                        /* fall through */
 160
 161                case FUNCMUX_SDMMC4_ATB_GMA_4_BIT:
 162                        pinmux_set_func(PINGRP_ATB, PMUX_FUNC_SDIO4);
 163                        pinmux_set_func(PINGRP_GMA, PMUX_FUNC_SDIO4);
 164
 165                        pinmux_tristate_disable(PINGRP_ATB);
 166                        pinmux_tristate_disable(PINGRP_GMA);
 167                        bad_config = 0;
 168                        break;
 169                }
 170                break;
 171
 172        default:
 173                debug("%s: invalid periph_id %d", __func__, id);
 174                return -1;
 175        }
 176
 177        if (bad_config) {
 178                debug("%s: invalid config %d for periph_id %d", __func__,
 179                      config, id);
 180                return -1;
 181        }
 182
 183        return 0;
 184}
 185