int funcmux_select(enum periph_id id, int config) { int bad_config = config != FUNCMUX_DEFAULT; switch (id) { case PERIPH_ID_UART1: switch (config) { case FUNCMUX_UART1_ULPI: pinmux_set_func(PINGRP_ULPI_DATA0, PMUX_FUNC_UARTA); pinmux_set_func(PINGRP_ULPI_DATA1, PMUX_FUNC_UARTA); pinmux_set_func(PINGRP_ULPI_DATA2, PMUX_FUNC_UARTA); pinmux_set_func(PINGRP_ULPI_DATA3, PMUX_FUNC_UARTA); pinmux_tristate_disable(PINGRP_ULPI_DATA0); pinmux_tristate_disable(PINGRP_ULPI_DATA1); pinmux_tristate_disable(PINGRP_ULPI_DATA2); pinmux_tristate_disable(PINGRP_ULPI_DATA3); break; } break; /* Add other periph IDs here as needed */ default: debug("%s: invalid periph_id %d", __func__, id); return -1; } if (bad_config) { debug("%s: invalid config %d for periph_id %d", __func__, config, id); return -1; } return 0; }
void pinmux_config_pingroup(const struct pingroup_config *config) { enum pmux_pingrp pin = config->pingroup; pinmux_set_func(pin, config->func); pinmux_set_pullupdown(pin, config->pull); pinmux_set_tristate(pin, config->tristate); }
void pin_mux_usb(void) { funcmux_select(PERIPH_ID_USB2, FUNCMUX_USB2_ULPI); pinmux_set_func(PINGRP_CDEV2, PMUX_FUNC_PLLP_OUT4); pinmux_tristate_disable(PINGRP_CDEV2); /* USB2 PHY reset GPIO */ pinmux_tristate_disable(PINGRP_UAC); }
/** * Handle the next stage of device init */ static int handle_stage(const void *blob, struct tegra_lcd_priv *priv) { debug("%s: stage %d\n", __func__, priv->stage); /* do the things for this stage */ switch (priv->stage) { case STAGE_START: /* * It is possible that the FDT has requested that the LCD be * disabled. We currently don't support this. It would require * changes to U-Boot LCD subsystem to have LCD support * compiled in but not used. An easier option might be to * still have a frame buffer, but leave the backlight off and * remove all mention of lcd in the stdout environment * variable. */ funcmux_select(PERIPH_ID_DISP1, FUNCMUX_DEFAULT); break; case STAGE_PANEL_VDD: if (dm_gpio_is_valid(&priv->panel_vdd)) dm_gpio_set_value(&priv->panel_vdd, 1); break; case STAGE_LVDS: if (dm_gpio_is_valid(&priv->lvds_shutdown)) dm_gpio_set_value(&priv->lvds_shutdown, 1); break; case STAGE_BACKLIGHT_VDD: if (dm_gpio_is_valid(&priv->backlight_vdd)) dm_gpio_set_value(&priv->backlight_vdd, 1); break; case STAGE_PWM: /* Enable PWM at 15/16 high, 32768 Hz with divider 1 */ pinmux_set_func(PMUX_PINGRP_GPU, PMUX_FUNC_PWM); pinmux_tristate_disable(PMUX_PINGRP_GPU); pwm_set_config(priv->pwm, priv->pwm_channel, 0xdf, 0xff); pwm_set_enable(priv->pwm, priv->pwm_channel, true); break; case STAGE_BACKLIGHT_EN: if (dm_gpio_is_valid(&priv->backlight_en)) dm_gpio_set_value(&priv->backlight_en, 1); break; case STAGE_DONE: break; } /* set up timer for next stage */ priv->timer_next = timer_get_us(); if (priv->stage < FDT_LCD_TIMINGS) priv->timer_next += priv->panel_timings[priv->stage] * 1000; /* move to next stage */ priv->stage++; return 0; }
void pin_mux_usb(void) { /* For USB0's GPIO PD0. For now, since we have no pinmux in fdt */ pinmux_tristate_disable(PMUX_PINGRP_SLXK); /* For USB1's ULPI signals */ funcmux_select(PERIPH_ID_USB2, FUNCMUX_USB2_ULPI); pinmux_set_func(PMUX_PINGRP_CDEV2, PMUX_FUNC_PLLP_OUT4); pinmux_tristate_disable(PMUX_PINGRP_CDEV2); /* USB1 PHY reset GPIO */ pinmux_tristate_disable(PMUX_PINGRP_UAC); }
/* * Routine: pin_mux_mmc * Description: setup the pin muxes/tristate values for the SDMMC(s) */ static void pin_mux_mmc(void) { /* SDMMC4: config 3, x8 on 2nd set of pins */ pinmux_set_func(PINGRP_ATB, PMUX_FUNC_SDIO4); pinmux_set_func(PINGRP_GMA, PMUX_FUNC_SDIO4); pinmux_set_func(PINGRP_GME, PMUX_FUNC_SDIO4); pinmux_tristate_disable(PINGRP_ATB); pinmux_tristate_disable(PINGRP_GMA); pinmux_tristate_disable(PINGRP_GME); /* SDMMC1: SDIO1_CLK, SDIO1_CMD, SDIO1_DAT[3:0] */ pinmux_set_func(PINGRP_SDMMC1, PMUX_FUNC_SDIO1); pinmux_tristate_disable(PINGRP_SDMMC1); /* For power GPIO PV1 */ pinmux_tristate_disable(PINGRP_UAC); /* For CD GPIO PI5 */ pinmux_tristate_disable(PINGRP_ATC); }
void pinmux_config_pingroup(struct pingroup_config *config) { enum pmux_pingrp pin = config->pingroup; pinmux_set_func(pin, config->func); pinmux_set_pullupdown(pin, config->pull); pinmux_set_tristate(pin, config->tristate); pinmux_set_io(pin, config->io); pinmux_set_lock(pin, config->lock); pinmux_set_od(pin, config->od); pinmux_set_ioreset(pin, config->ioreset); }
void colibri_t20_common_pin_mux_usb(void) { /* module internal USB bus to connect ethernet chipset */ funcmux_select(PERIPH_ID_USB2, FUNCMUX_USB2_ULPI); /* ULPI reference clock output */ pinmux_set_func(PMUX_PINGRP_CDEV2, PMUX_FUNC_PLLP_OUT4); pinmux_tristate_disable(PMUX_PINGRP_CDEV2); /* PHY reset GPIO */ pinmux_tristate_disable(PMUX_PINGRP_UAC); /* VBus GPIO */ pinmux_tristate_disable(PMUX_PINGRP_DTE); }
int funcmux_select(enum periph_id id, int config) { int bad_config = config != FUNCMUX_DEFAULT; switch (id) { case PERIPH_ID_UART4: switch (config) { case FUNCMUX_UART4_GMI: pinmux_set_func(PINGRP_GMI_A16, PMUX_FUNC_UARTD); pinmux_set_func(PINGRP_GMI_A17, PMUX_FUNC_UARTD); pinmux_set_func(PINGRP_GMI_A18, PMUX_FUNC_UARTD); pinmux_set_func(PINGRP_GMI_A19, PMUX_FUNC_UARTD); pinmux_set_io(PINGRP_GMI_A16, PMUX_PIN_OUTPUT); pinmux_set_io(PINGRP_GMI_A17, PMUX_PIN_INPUT); pinmux_set_io(PINGRP_GMI_A18, PMUX_PIN_INPUT); pinmux_set_io(PINGRP_GMI_A19, PMUX_PIN_OUTPUT); pinmux_tristate_disable(PINGRP_GMI_A16); pinmux_tristate_disable(PINGRP_GMI_A17); pinmux_tristate_disable(PINGRP_GMI_A18); pinmux_tristate_disable(PINGRP_GMI_A19); break; } break; /* Add other periph IDs here as needed */ default: debug("%s: invalid periph_id %d", __func__, id); return -1; } if (bad_config) { debug("%s: invalid config %d for periph_id %d", __func__, config, id); return -1; } return 0; }
static int tegra20_sflash_claim_bus(struct udevice *dev) { struct udevice *bus = dev->parent; struct tegra20_sflash_priv *priv = dev_get_priv(bus); struct spi_regs *regs = priv->regs; u32 reg; /* Change SPI clock to correct frequency, PLLP_OUT0 source */ clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq); /* Clear stale status here */ reg = SPI_STAT_RDY | SPI_STAT_RXF_FLUSH | SPI_STAT_TXF_FLUSH | \ SPI_STAT_RXF_UNR | SPI_STAT_TXF_OVF; writel(reg, ®s->status); debug("%s: STATUS = %08x\n", __func__, readl(®s->status)); /* * Use sw-controlled CS, so we can clock in data after ReadID, etc. */ reg = (priv->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT; if (priv->mode & 2) reg |= 1 << SPI_CMD_ACTIVE_SCLK_SHIFT; clrsetbits_le32(®s->command, SPI_CMD_ACTIVE_SCLK_MASK | SPI_CMD_ACTIVE_SDA_MASK, SPI_CMD_CS_SOFT | reg); debug("%s: COMMAND = %08x\n", __func__, readl(®s->command)); /* * SPI pins on Tegra20 are muxed - change pinmux later due to UART * issue. */ pinmux_set_func(PMUX_PINGRP_GMD, PMUX_FUNC_SFLASH); pinmux_tristate_disable(PMUX_PINGRP_LSPI); pinmux_set_func(PMUX_PINGRP_GMC, PMUX_FUNC_SFLASH); return 0; }
int funcmux_select(enum periph_id id, int config) { int bad_config = config != FUNCMUX_DEFAULT; switch (id) { case PERIPH_ID_UART4: switch (config) { case FUNCMUX_UART4_GPIO: /* TXD,RXD,CTS,RTS */ pinmux_set_func(PMUX_PINGRP_PJ7, PMUX_FUNC_UARTD); pinmux_set_func(PMUX_PINGRP_PB0, PMUX_FUNC_UARTD); pinmux_set_func(PMUX_PINGRP_PB1, PMUX_FUNC_UARTD); pinmux_set_func(PMUX_PINGRP_PK7, PMUX_FUNC_UARTD); pinmux_set_io(PMUX_PINGRP_PJ7, PMUX_PIN_OUTPUT); pinmux_set_io(PMUX_PINGRP_PB0, PMUX_PIN_INPUT); pinmux_set_io(PMUX_PINGRP_PB1, PMUX_PIN_INPUT); pinmux_set_io(PMUX_PINGRP_PK7, PMUX_PIN_OUTPUT); pinmux_tristate_disable(PMUX_PINGRP_PJ7); pinmux_tristate_disable(PMUX_PINGRP_PB0); pinmux_tristate_disable(PMUX_PINGRP_PB1); pinmux_tristate_disable(PMUX_PINGRP_PK7); break; } break; case PERIPH_ID_UART1: switch (config) { case FUNCMUX_UART1_KBC: pinmux_set_func(PMUX_PINGRP_KB_ROW9_PS1, PMUX_FUNC_UARTA); pinmux_set_func(PMUX_PINGRP_KB_ROW10_PS2, PMUX_FUNC_UARTA); pinmux_set_io(PMUX_PINGRP_KB_ROW9_PS1, PMUX_PIN_OUTPUT); pinmux_set_io(PMUX_PINGRP_KB_ROW10_PS2, PMUX_PIN_INPUT); pinmux_tristate_disable(PMUX_PINGRP_KB_ROW9_PS1); pinmux_tristate_disable(PMUX_PINGRP_KB_ROW10_PS2); break; } break; /* Add other periph IDs here as needed */ default: debug("%s: invalid periph_id %d", __func__, id); return -1; } if (bad_config) { debug("%s: invalid config %d for periph_id %d", __func__, config, id); return -1; } return 0; }
int arch_misc_init(void) { /* Disable PMIC sleep mode on low supply voltage */ struct udevice *dev; u8 addr, data[1]; int err; err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); if (err) { debug("%s: Cannot find PMIC I2C chip\n", __func__); return err; } addr = PMU_SUPPLYENE; err = dm_i2c_read(dev, addr, data, 1); if (err) { debug("failed to get PMU_SUPPLYENE\n"); return err; } data[0] &= ~PMU_SUPPLYENE_SYSINEN; data[0] |= PMU_SUPPLYENE_EXITSLREQ; err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to set PMU_SUPPLYENE\n"); return err; } /* make sure SODIMM pin 87 nRESET_OUT is released properly */ pinmux_set_func(PMUX_PINGRP_ATA, PMUX_FUNC_GMI); if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) == NVBOOTTYPE_RECOVERY) printf("USB recovery mode\n"); return 0; }
static void i2c_pin_mux_select(struct i2c_bus *i2c_bus, int pinmux_config) { switch (i2c_bus->periph_id) { case PERIPH_ID_DVC_I2C: /* DVC I2C (I2CP) */ /* there is only one selection, pinmux_config is ignored */ pinmux_set_func(PINGRP_I2CP, PMUX_FUNC_I2C); break; case PERIPH_ID_I2C1: /* I2C1 */ /* support pinmux_config of 1 for now, */ pinmux_set_func(PINGRP_RM, PMUX_FUNC_I2C); break; case PERIPH_ID_I2C2: /* I2C2 */ switch (pinmux_config) { case 1: /* DDC pin group, select I2C2 */ pinmux_set_func(PINGRP_DDC, PMUX_FUNC_I2C2); /* PTA to HDMI */ pinmux_set_func(PINGRP_PTA, PMUX_FUNC_HDMI); break; case 2: /* PTA pin group, select I2C2 */ pinmux_set_func(PINGRP_PTA, PMUX_FUNC_I2C2); /* set DDC_SEL to RSVDx (RSVD2 works for now) */ pinmux_set_func(PINGRP_DDC, PMUX_FUNC_RSVD2); break; default: printf("bad pinmux_config(%d): pinmux select ignored\n", pinmux_config); break; } break; case PERIPH_ID_I2C3: /* I2C3 */ /* support pinmux_config of 1 for now */ pinmux_set_func(PINGRP_DTF, PMUX_FUNC_I2C3); break; default: break; } }
/** * Handle the next stage of device init */ static int handle_stage(const void *blob) { debug("%s: stage %d\n", __func__, stage); /* do the things for this stage */ switch (stage) { case STAGE_START: /* Initialize the Tegra display controller */ if (tegra_display_probe(gd->fdt_blob, (void *)gd->fb_base)) { printf("%s: Failed to probe display driver\n", __func__); return -1; } /* get panel details */ if (fdt_decode_lcd(blob, &config)) { printf("No valid LCD information in device tree\n"); return -1; } /* * It is possible that the FDT has requested that the LCD be * disabled. We currently don't support this. It would require * changes to U-Boot LCD subsystem to have LCD support * compiled in but not used. An easier option might be to * still have a frame buffer, but leave the backlight off and * remove all mention of lcd in the stdout environment * variable. */ funcmux_select(PERIPH_ID_DISP1, FUNCMUX_DEFAULT); fdtdec_setup_gpio(&config.panel_vdd); fdtdec_setup_gpio(&config.lvds_shutdown); fdtdec_setup_gpio(&config.backlight_vdd); fdtdec_setup_gpio(&config.backlight_en); /* * TODO: If fdt includes output flag we can omit this code * since fdtdec_setup_gpio will do it for us. */ if (fdt_gpio_isvalid(&config.panel_vdd)) gpio_direction_output(config.panel_vdd.gpio, 0); if (fdt_gpio_isvalid(&config.lvds_shutdown)) gpio_direction_output(config.lvds_shutdown.gpio, 0); if (fdt_gpio_isvalid(&config.backlight_vdd)) gpio_direction_output(config.backlight_vdd.gpio, 0); if (fdt_gpio_isvalid(&config.backlight_en)) gpio_direction_output(config.backlight_en.gpio, 0); break; case STAGE_PANEL_VDD: if (fdt_gpio_isvalid(&config.panel_vdd)) gpio_direction_output(config.panel_vdd.gpio, 1); break; case STAGE_LVDS: if (fdt_gpio_isvalid(&config.lvds_shutdown)) gpio_set_value(config.lvds_shutdown.gpio, 1); break; case STAGE_BACKLIGHT_VDD: if (fdt_gpio_isvalid(&config.backlight_vdd)) gpio_set_value(config.backlight_vdd.gpio, 1); break; case STAGE_PWM: /* Enable PWM at 15/16 high, 32768 Hz with divider 1 */ pinmux_set_func(PINGRP_GPU, PMUX_FUNC_PWM); pinmux_tristate_disable(PINGRP_GPU); pwm_enable(config.pwm_channel, 32768, 0xdf, 1); break; case STAGE_BACKLIGHT_EN: if (fdt_gpio_isvalid(&config.backlight_en)) gpio_set_value(config.backlight_en.gpio, 1); break; case STAGE_DONE: break; } /* set up timer for next stage */ timer_next = timer_get_us(); if (stage < FDT_LCD_TIMINGS) timer_next += config.panel_timings[stage] * 1000; /* move to next stage */ stage++; return 0; }
void pin_mux_display(void) { pinmux_set_func(PINGRP_SDC, PMUX_FUNC_PWM); pinmux_tristate_disable(PINGRP_SDC); }
int funcmux_select(enum periph_id id, int config) { int bad_config = config != FUNCMUX_DEFAULT; switch (id) { case PERIPH_ID_UART1: if (config == FUNCMUX_UART1_IRRX_IRTX) { pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA); pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA); pinmux_tristate_disable(PINGRP_IRRX); pinmux_tristate_disable(PINGRP_IRTX); /* * Tegra appears to boot with function UARTA pre- * selected on mux group SDB. If two mux groups are * both set to the same function, it's unclear which * group's pins drive the RX signals into the HW. * For UARTA, SDB certainly overrides group IRTX in * practice. To solve this, configure some alternative * function on SDB to avoid the conflict. Also, tri- * state the group to avoid driving any signal onto it * until we know what's connected. */ pinmux_tristate_enable(PINGRP_SDB); pinmux_set_func(PINGRP_SDB, PMUX_FUNC_SDIO3); } break; case PERIPH_ID_UART2: if (config == FUNCMUX_UART2_IRDA) { pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA); pinmux_tristate_disable(PINGRP_UAD); } break; case PERIPH_ID_UART4: if (config == FUNCMUX_UART4_GMC) { pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD); pinmux_tristate_disable(PINGRP_GMC); } break; case PERIPH_ID_DVC_I2C: /* there is only one selection, pinmux_config is ignored */ if (config == FUNCMUX_DVC_I2CP) { pinmux_set_func(PINGRP_I2CP, PMUX_FUNC_I2C); pinmux_tristate_disable(PINGRP_I2CP); } break; case PERIPH_ID_I2C1: /* support pinmux_config of 0 for now, */ if (config == FUNCMUX_I2C1_RM) { pinmux_set_func(PINGRP_RM, PMUX_FUNC_I2C); pinmux_tristate_disable(PINGRP_RM); } break; case PERIPH_ID_I2C2: /* I2C2 */ switch (config) { case FUNCMUX_I2C2_DDC: /* DDC pin group, select I2C2 */ pinmux_set_func(PINGRP_DDC, PMUX_FUNC_I2C2); /* PTA to HDMI */ pinmux_set_func(PINGRP_PTA, PMUX_FUNC_HDMI); pinmux_tristate_disable(PINGRP_DDC); break; case FUNCMUX_I2C2_PTA: /* PTA pin group, select I2C2 */ pinmux_set_func(PINGRP_PTA, PMUX_FUNC_I2C2); /* set DDC_SEL to RSVDx (RSVD2 works for now) */ pinmux_set_func(PINGRP_DDC, PMUX_FUNC_RSVD2); pinmux_tristate_disable(PINGRP_PTA); bad_config = 0; break; } break; case PERIPH_ID_I2C3: /* I2C3 */ /* support pinmux_config of 0 for now */ if (config == FUNCMUX_I2C3_DTF) { pinmux_set_func(PINGRP_DTF, PMUX_FUNC_I2C3); pinmux_tristate_disable(PINGRP_DTF); } break; case PERIPH_ID_SDMMC2: if (config == FUNCMUX_SDMMC2_DTA_DTD_8BIT) { pinmux_set_func(PINGRP_DTA, PMUX_FUNC_SDIO2); pinmux_set_func(PINGRP_DTD, PMUX_FUNC_SDIO2); pinmux_tristate_disable(PINGRP_DTA); pinmux_tristate_disable(PINGRP_DTD); } break; case PERIPH_ID_SDMMC3: switch (config) { case FUNCMUX_SDMMC3_SDB_SLXA_8BIT: pinmux_set_func(PINGRP_SLXA, PMUX_FUNC_SDIO3); pinmux_set_func(PINGRP_SLXC, PMUX_FUNC_SDIO3); pinmux_set_func(PINGRP_SLXD, PMUX_FUNC_SDIO3); pinmux_set_func(PINGRP_SLXK, PMUX_FUNC_SDIO3); pinmux_tristate_disable(PINGRP_SLXA); pinmux_tristate_disable(PINGRP_SLXC); pinmux_tristate_disable(PINGRP_SLXD); pinmux_tristate_disable(PINGRP_SLXK); /* fall through */ case FUNCMUX_SDMMC3_SDB_4BIT: pinmux_set_func(PINGRP_SDB, PMUX_FUNC_SDIO3); pinmux_set_func(PINGRP_SDC, PMUX_FUNC_SDIO3); pinmux_set_func(PINGRP_SDD, PMUX_FUNC_SDIO3); pinmux_tristate_disable(PINGRP_SDB); pinmux_tristate_disable(PINGRP_SDC); pinmux_tristate_disable(PINGRP_SDD); bad_config = 0; break; } break; case PERIPH_ID_SDMMC4: switch (config) { case FUNCMUX_SDMMC4_ATC_ATD_8BIT: pinmux_set_func(PINGRP_ATC, PMUX_FUNC_SDIO4); pinmux_set_func(PINGRP_ATD, PMUX_FUNC_SDIO4); pinmux_tristate_disable(PINGRP_ATC); pinmux_tristate_disable(PINGRP_ATD); break; case FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT: pinmux_set_func(PINGRP_GME, PMUX_FUNC_SDIO4); pinmux_tristate_disable(PINGRP_GME); /* fall through */ case FUNCMUX_SDMMC4_ATB_GMA_4_BIT: pinmux_set_func(PINGRP_ATB, PMUX_FUNC_SDIO4); pinmux_set_func(PINGRP_GMA, PMUX_FUNC_SDIO4); pinmux_tristate_disable(PINGRP_ATB); pinmux_tristate_disable(PINGRP_GMA); bad_config = 0; break; } break; case PERIPH_ID_KBC: if (config == FUNCMUX_DEFAULT) { enum pmux_pingrp grp[] = {PINGRP_KBCA, PINGRP_KBCB, PINGRP_KBCC, PINGRP_KBCD, PINGRP_KBCE, PINGRP_KBCF }; int i; for (i = 0; i < ARRAY_SIZE(grp); i++) { pinmux_tristate_disable(grp[i]); pinmux_set_func(grp[i], PMUX_FUNC_KBC); pinmux_set_pullupdown(grp[i], PMUX_PULL_UP); } break; } default: debug("%s: invalid periph_id %d", __func__, id); return -1; } if (bad_config) { debug("%s: invalid config %d for periph_id %d", __func__, config, id); return -1; } return 0; }