commit
ace97d2617
@ -1,7 +0,0 @@ |
||||
#
|
||||
# Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Allow NEON instructions (needed for lowlevel_init.S with GNU toolchain)
|
||||
PLATFORM_RELFLAGS += -mfpu=neon
|
@ -0,0 +1,242 @@ |
||||
/*
|
||||
* (C) Copyright 2014 - 2015 Xilinx, Inc. |
||||
* Michal Simek <michal.simek@xilinx.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/hardware.h> |
||||
#include <asm/arch/sys_proto.h> |
||||
#include <asm/io.h> |
||||
|
||||
#define LOCK 0 |
||||
#define SPLIT 1 |
||||
|
||||
#define HALT 0 |
||||
#define RELEASE 1 |
||||
|
||||
#define ZYNQMP_BOOTADDR_HIGH_MASK 0xFFFFFFFF |
||||
#define ZYNQMP_R5_HIVEC_ADDR 0xFFFF0000 |
||||
#define ZYNQMP_R5_LOVEC_ADDR 0x0 |
||||
#define ZYNQMP_RPU_CFG_CPU_HALT_MASK 0x01 |
||||
#define ZYNQMP_RPU_CFG_HIVEC_MASK 0x04 |
||||
#define ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK 0x08 |
||||
#define ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK 0x40 |
||||
#define ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK 0x10 |
||||
|
||||
#define ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK 0x04 |
||||
#define ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK 0x01 |
||||
#define ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK 0x02 |
||||
#define ZYNQMP_CRLAPB_CPU_R5_CTRL_CLKACT_MASK 0x1000000 |
||||
|
||||
#define ZYNQMP_TCM_START_ADDRESS 0xFFE00000 |
||||
#define ZYNQMP_TCM_BOTH_SIZE 0x40000 |
||||
|
||||
#define ZYNQMP_CORE_APU0 0 |
||||
#define ZYNQMP_CORE_APU3 3 |
||||
|
||||
#define ZYNQMP_MAX_CORES 6 |
||||
|
||||
int is_core_valid(unsigned int core) |
||||
{ |
||||
if (core < ZYNQMP_MAX_CORES) |
||||
return 1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int cpu_reset(int nr) |
||||
{ |
||||
puts("Feature is not implemented.\n"); |
||||
return 0; |
||||
} |
||||
|
||||
static void set_r5_halt_mode(u8 halt, u8 mode) |
||||
{ |
||||
u32 tmp; |
||||
|
||||
tmp = readl(&rpu_base->rpu0_cfg); |
||||
if (halt == HALT) |
||||
tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK; |
||||
else |
||||
tmp |= ZYNQMP_RPU_CFG_CPU_HALT_MASK; |
||||
writel(tmp, &rpu_base->rpu0_cfg); |
||||
|
||||
if (mode == LOCK) { |
||||
tmp = readl(&rpu_base->rpu1_cfg); |
||||
if (halt == HALT) |
||||
tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK; |
||||
else |
||||
tmp |= ZYNQMP_RPU_CFG_CPU_HALT_MASK; |
||||
writel(tmp, &rpu_base->rpu1_cfg); |
||||
} |
||||
} |
||||
|
||||
static void set_r5_tcm_mode(u8 mode) |
||||
{ |
||||
u32 tmp; |
||||
|
||||
tmp = readl(&rpu_base->rpu_glbl_ctrl); |
||||
if (mode == LOCK) { |
||||
tmp &= ~ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK; |
||||
tmp |= ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK | |
||||
ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK; |
||||
} else { |
||||
tmp |= ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK; |
||||
tmp &= ~(ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK | |
||||
ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK); |
||||
} |
||||
|
||||
writel(tmp, &rpu_base->rpu_glbl_ctrl); |
||||
} |
||||
|
||||
static void set_r5_reset(u8 mode) |
||||
{ |
||||
u32 tmp; |
||||
|
||||
tmp = readl(&crlapb_base->rst_lpd_top); |
||||
tmp |= (ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK | |
||||
ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK); |
||||
|
||||
if (mode == LOCK) |
||||
tmp |= ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK; |
||||
|
||||
writel(tmp, &crlapb_base->rst_lpd_top); |
||||
} |
||||
|
||||
static void release_r5_reset(u8 mode) |
||||
{ |
||||
u32 tmp; |
||||
|
||||
tmp = readl(&crlapb_base->rst_lpd_top); |
||||
tmp &= ~(ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK | |
||||
ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK); |
||||
|
||||
if (mode == LOCK) |
||||
tmp &= ~ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK; |
||||
|
||||
writel(tmp, &crlapb_base->rst_lpd_top); |
||||
} |
||||
|
||||
static void enable_clock_r5(void) |
||||
{ |
||||
u32 tmp; |
||||
|
||||
tmp = readl(&crlapb_base->cpu_r5_ctrl); |
||||
tmp |= ZYNQMP_CRLAPB_CPU_R5_CTRL_CLKACT_MASK; |
||||
writel(tmp, &crlapb_base->cpu_r5_ctrl); |
||||
|
||||
/* Give some delay for clock
|
||||
* to propogate */ |
||||
udelay(0x500); |
||||
} |
||||
|
||||
int cpu_disable(int nr) |
||||
{ |
||||
if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) { |
||||
u32 val = readl(&crfapb_base->rst_fpd_apu); |
||||
val |= 1 << nr; |
||||
writel(val, &crfapb_base->rst_fpd_apu); |
||||
} else { |
||||
set_r5_reset(LOCK); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int cpu_status(int nr) |
||||
{ |
||||
if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) { |
||||
u32 addr_low = readl(((u8 *)&apu_base->rvbar_addr0_l) + nr * 8); |
||||
u32 addr_high = readl(((u8 *)&apu_base->rvbar_addr0_h) + |
||||
nr * 8); |
||||
u32 val = readl(&crfapb_base->rst_fpd_apu); |
||||
val &= 1 << nr; |
||||
printf("APU CPU%d %s - starting address HI: %x, LOW: %x\n", |
||||
nr, val ? "OFF" : "ON" , addr_high, addr_low); |
||||
} else { |
||||
u32 val = readl(&crlapb_base->rst_lpd_top); |
||||
val &= 1 << (nr - 4); |
||||
printf("RPU CPU%d %s\n", nr - 4, val ? "OFF" : "ON"); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static void set_r5_start(u8 high) |
||||
{ |
||||
u32 tmp; |
||||
|
||||
tmp = readl(&rpu_base->rpu0_cfg); |
||||
if (high) |
||||
tmp |= ZYNQMP_RPU_CFG_HIVEC_MASK; |
||||
else |
||||
tmp &= ~ZYNQMP_RPU_CFG_HIVEC_MASK; |
||||
writel(tmp, &rpu_base->rpu0_cfg); |
||||
|
||||
tmp = readl(&rpu_base->rpu1_cfg); |
||||
if (high) |
||||
tmp |= ZYNQMP_RPU_CFG_HIVEC_MASK; |
||||
else |
||||
tmp &= ~ZYNQMP_RPU_CFG_HIVEC_MASK; |
||||
writel(tmp, &rpu_base->rpu1_cfg); |
||||
} |
||||
|
||||
int cpu_release(int nr, int argc, char * const argv[]) |
||||
{ |
||||
if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) { |
||||
u64 boot_addr = simple_strtoull(argv[0], NULL, 16); |
||||
/* HIGH */ |
||||
writel((u32)(boot_addr >> 32), |
||||
((u8 *)&apu_base->rvbar_addr0_h) + nr * 8); |
||||
/* LOW */ |
||||
writel((u32)(boot_addr & ZYNQMP_BOOTADDR_HIGH_MASK), |
||||
((u8 *)&apu_base->rvbar_addr0_l) + nr * 8); |
||||
|
||||
u32 val = readl(&crfapb_base->rst_fpd_apu); |
||||
val &= ~(1 << nr); |
||||
writel(val, &crfapb_base->rst_fpd_apu); |
||||
} else { |
||||
if (argc != 2) { |
||||
printf("Invalid number of arguments to release.\n"); |
||||
printf("<addr> <mode>-Start addr lockstep or split\n"); |
||||
return 1; |
||||
} |
||||
|
||||
u32 boot_addr = simple_strtoul(argv[0], NULL, 16); |
||||
if (!(boot_addr == ZYNQMP_R5_LOVEC_ADDR || |
||||
boot_addr == ZYNQMP_R5_HIVEC_ADDR)) { |
||||
printf("Invalid starting address 0x%x\n", boot_addr); |
||||
printf("0 or 0xffff0000 are permitted\n"); |
||||
return 1; |
||||
} |
||||
|
||||
if (!strncmp(argv[1], "lockstep", 8)) { |
||||
printf("R5 lockstep mode\n"); |
||||
set_r5_tcm_mode(LOCK); |
||||
set_r5_halt_mode(HALT, LOCK); |
||||
|
||||
if (boot_addr == 0) |
||||
set_r5_start(0); |
||||
else |
||||
set_r5_start(1); |
||||
|
||||
enable_clock_r5(); |
||||
release_r5_reset(LOCK); |
||||
set_r5_halt_mode(RELEASE, LOCK); |
||||
} else if (!strncmp(argv[1], "split", 5)) { |
||||
printf("R5 split mode\n"); |
||||
set_r5_tcm_mode(SPLIT); |
||||
set_r5_halt_mode(HALT, SPLIT); |
||||
enable_clock_r5(); |
||||
release_r5_reset(SPLIT); |
||||
set_r5_halt_mode(RELEASE, SPLIT); |
||||
} else { |
||||
printf("Unsupported mode\n"); |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,23 @@ |
||||
/* |
||||
* Avnet PicoZed board DTS |
||||
* |
||||
* Copyright (C) 2015 Xilinx, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
/dts-v1/; |
||||
#include "zynq-7000.dtsi" |
||||
|
||||
/ { |
||||
model = "Zynq PicoZed Board"; |
||||
compatible = "xlnx,zynq-picozed", "xlnx,zynq-7000"; |
||||
|
||||
aliases { |
||||
serial0 = &uart1; |
||||
}; |
||||
|
||||
memory { |
||||
device_type = "memory"; |
||||
reg = <0 0x40000000>; |
||||
}; |
||||
}; |
@ -1,10 +0,0 @@ |
||||
/*
|
||||
* Copyright (c) 2013 Xilinx, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _ZYNQ_GPIO_H |
||||
#define _ZYNQ_GPIO_H |
||||
|
||||
#endif /* _ZYNQ_GPIO_H */ |
@ -0,0 +1,12 @@ |
||||
/*
|
||||
* Copyright 2015 Xilinx, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef __ARCH_ZYNQMP_GPIO_H |
||||
#define __ARCH_ZYNQMP_GPIO_H |
||||
|
||||
/* Empty file - sdhci requires this. */ |
||||
|
||||
#endif |
@ -0,0 +1,76 @@ |
||||
/*
|
||||
* Copyright (c) 2013 Xilinx, Inc. |
||||
* Copyright (c) 2015 DAVE Embedded Systems |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _ZYNQ_GPIO_H |
||||
#define _ZYNQ_GPIO_H |
||||
|
||||
#define ZYNQ_GPIO_BASE_ADDRESS 0xE000A000 |
||||
|
||||
/* Maximum banks */ |
||||
#define ZYNQ_GPIO_MAX_BANK 4 |
||||
|
||||
#define ZYNQ_GPIO_BANK0_NGPIO 32 |
||||
#define ZYNQ_GPIO_BANK1_NGPIO 22 |
||||
#define ZYNQ_GPIO_BANK2_NGPIO 32 |
||||
#define ZYNQ_GPIO_BANK3_NGPIO 32 |
||||
|
||||
#define ZYNQ_GPIO_NR_GPIOS (ZYNQ_GPIO_BANK0_NGPIO + \ |
||||
ZYNQ_GPIO_BANK1_NGPIO + \
|
||||
ZYNQ_GPIO_BANK2_NGPIO + \
|
||||
ZYNQ_GPIO_BANK3_NGPIO) |
||||
|
||||
#define ZYNQ_GPIO_BANK0_PIN_MIN 0 |
||||
#define ZYNQ_GPIO_BANK0_PIN_MAX (ZYNQ_GPIO_BANK0_PIN_MIN + \ |
||||
ZYNQ_GPIO_BANK0_NGPIO - 1) |
||||
#define ZYNQ_GPIO_BANK1_PIN_MIN (ZYNQ_GPIO_BANK0_PIN_MAX + 1) |
||||
#define ZYNQ_GPIO_BANK1_PIN_MAX (ZYNQ_GPIO_BANK1_PIN_MIN + \ |
||||
ZYNQ_GPIO_BANK1_NGPIO - 1) |
||||
#define ZYNQ_GPIO_BANK2_PIN_MIN (ZYNQ_GPIO_BANK1_PIN_MAX + 1) |
||||
#define ZYNQ_GPIO_BANK2_PIN_MAX (ZYNQ_GPIO_BANK2_PIN_MIN + \ |
||||
ZYNQ_GPIO_BANK2_NGPIO - 1) |
||||
#define ZYNQ_GPIO_BANK3_PIN_MIN (ZYNQ_GPIO_BANK2_PIN_MAX + 1) |
||||
#define ZYNQ_GPIO_BANK3_PIN_MAX (ZYNQ_GPIO_BANK3_PIN_MIN + \ |
||||
ZYNQ_GPIO_BANK3_NGPIO - 1) |
||||
|
||||
/* Register offsets for the GPIO device */ |
||||
/* LSW Mask & Data -WO */ |
||||
#define ZYNQ_GPIO_DATA_LSW_OFFSET(BANK) (0x000 + (8 * BANK)) |
||||
/* MSW Mask & Data -WO */ |
||||
#define ZYNQ_GPIO_DATA_MSW_OFFSET(BANK) (0x004 + (8 * BANK)) |
||||
/* Data Register-RW */ |
||||
#define ZYNQ_GPIO_DATA_RO_OFFSET(BANK) (0x060 + (4 * BANK)) |
||||
/* Direction mode reg-RW */ |
||||
#define ZYNQ_GPIO_DIRM_OFFSET(BANK) (0x204 + (0x40 * BANK)) |
||||
/* Output enable reg-RW */ |
||||
#define ZYNQ_GPIO_OUTEN_OFFSET(BANK) (0x208 + (0x40 * BANK)) |
||||
/* Interrupt mask reg-RO */ |
||||
#define ZYNQ_GPIO_INTMASK_OFFSET(BANK) (0x20C + (0x40 * BANK)) |
||||
/* Interrupt enable reg-WO */ |
||||
#define ZYNQ_GPIO_INTEN_OFFSET(BANK) (0x210 + (0x40 * BANK)) |
||||
/* Interrupt disable reg-WO */ |
||||
#define ZYNQ_GPIO_INTDIS_OFFSET(BANK) (0x214 + (0x40 * BANK)) |
||||
/* Interrupt status reg-RO */ |
||||
#define ZYNQ_GPIO_INTSTS_OFFSET(BANK) (0x218 + (0x40 * BANK)) |
||||
/* Interrupt type reg-RW */ |
||||
#define ZYNQ_GPIO_INTTYPE_OFFSET(BANK) (0x21C + (0x40 * BANK)) |
||||
/* Interrupt polarity reg-RW */ |
||||
#define ZYNQ_GPIO_INTPOL_OFFSET(BANK) (0x220 + (0x40 * BANK)) |
||||
/* Interrupt on any, reg-RW */ |
||||
#define ZYNQ_GPIO_INTANY_OFFSET(BANK) (0x224 + (0x40 * BANK)) |
||||
|
||||
/* Disable all interrupts mask */ |
||||
#define ZYNQ_GPIO_IXR_DISABLE_ALL 0xFFFFFFFF |
||||
|
||||
/* Mid pin number of a bank */ |
||||
#define ZYNQ_GPIO_MID_PIN_NUM 16 |
||||
|
||||
/* GPIO upper 16 bit mask */ |
||||
#define ZYNQ_GPIO_UPPER_MASK 0xFFFF0000 |
||||
|
||||
#define BIT(x) (1<<x) |
||||
|
||||
#endif /* _ZYNQ_GPIO_H */ |
@ -1,2 +1 @@ |
||||
ps7_init.[ch] |
||||
ps7_init_gpl.[ch] |
||||
|
@ -1,2 +0,0 @@ |
||||
|
||||
#warning usage of ps7_init files is deprecated please use ps7_init_gpl |
@ -0,0 +1,6 @@ |
||||
CONFIG_SPL=y |
||||
CONFIG_ARM=y |
||||
CONFIG_ARCH_ZYNQ=y |
||||
CONFIG_TARGET_ZYNQ_PICOZED=y |
||||
CONFIG_OF_CONTROL=n |
||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed" |
@ -0,0 +1,220 @@ |
||||
/*
|
||||
* Xilinx Zynq GPIO device driver |
||||
* |
||||
* Copyright (C) 2015 DAVE Embedded Systems <devel@dave.eu> |
||||
* |
||||
* Most of code taken from linux kernel driver (linux/drivers/gpio/gpio-zynq.c) |
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/gpio.h> |
||||
#include <asm/io.h> |
||||
#include <asm/errno.h> |
||||
|
||||
/**
|
||||
* zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank |
||||
* for a given pin in the GPIO device |
||||
* @pin_num: gpio pin number within the device |
||||
* @bank_num: an output parameter used to return the bank number of the gpio |
||||
* pin |
||||
* @bank_pin_num: an output parameter used to return pin number within a bank |
||||
* for the given gpio pin |
||||
* |
||||
* Returns the bank number and pin offset within the bank. |
||||
*/ |
||||
static inline void zynq_gpio_get_bank_pin(unsigned int pin_num, |
||||
unsigned int *bank_num, |
||||
unsigned int *bank_pin_num) |
||||
{ |
||||
switch (pin_num) { |
||||
case ZYNQ_GPIO_BANK0_PIN_MIN ... ZYNQ_GPIO_BANK0_PIN_MAX: |
||||
*bank_num = 0; |
||||
*bank_pin_num = pin_num; |
||||
break; |
||||
case ZYNQ_GPIO_BANK1_PIN_MIN ... ZYNQ_GPIO_BANK1_PIN_MAX: |
||||
*bank_num = 1; |
||||
*bank_pin_num = pin_num - ZYNQ_GPIO_BANK1_PIN_MIN; |
||||
break; |
||||
case ZYNQ_GPIO_BANK2_PIN_MIN ... ZYNQ_GPIO_BANK2_PIN_MAX: |
||||
*bank_num = 2; |
||||
*bank_pin_num = pin_num - ZYNQ_GPIO_BANK2_PIN_MIN; |
||||
break; |
||||
case ZYNQ_GPIO_BANK3_PIN_MIN ... ZYNQ_GPIO_BANK3_PIN_MAX: |
||||
*bank_num = 3; |
||||
*bank_pin_num = pin_num - ZYNQ_GPIO_BANK3_PIN_MIN; |
||||
break; |
||||
default: |
||||
printf("invalid GPIO pin number: %u\n", pin_num); |
||||
*bank_num = 0; |
||||
*bank_pin_num = 0; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
int gpio_is_valid(unsigned gpio) |
||||
{ |
||||
return (gpio >= 0) && (gpio < ZYNQ_GPIO_NR_GPIOS); |
||||
} |
||||
|
||||
static int check_gpio(unsigned gpio) |
||||
{ |
||||
if (!gpio_is_valid(gpio)) { |
||||
printf("ERROR : check_gpio: invalid GPIO %d\n", gpio); |
||||
return -1; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* gpio_get_value - Get the state of the specified pin of GPIO device |
||||
* @gpio: gpio pin number within the device |
||||
* |
||||
* This function reads the state of the specified pin of the GPIO device. |
||||
* |
||||
* Return: 0 if the pin is low, 1 if pin is high. |
||||
*/ |
||||
int gpio_get_value(unsigned gpio) |
||||
{ |
||||
u32 data; |
||||
unsigned int bank_num, bank_pin_num; |
||||
|
||||
if (check_gpio(gpio) < 0) |
||||
return -1; |
||||
|
||||
zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); |
||||
|
||||
data = readl(ZYNQ_GPIO_BASE_ADDRESS + |
||||
ZYNQ_GPIO_DATA_RO_OFFSET(bank_num)); |
||||
|
||||
return (data >> bank_pin_num) & 1; |
||||
} |
||||
|
||||
/**
|
||||
* gpio_set_value - Modify the value of the pin with specified value |
||||
* @gpio: gpio pin number within the device |
||||
* @value: value used to modify the value of the specified pin |
||||
* |
||||
* This function calculates the register offset (i.e to lower 16 bits or |
||||
* upper 16 bits) based on the given pin number and sets the value of a |
||||
* gpio pin to the specified value. The value is either 0 or non-zero. |
||||
*/ |
||||
int gpio_set_value(unsigned gpio, int value) |
||||
{ |
||||
unsigned int reg_offset, bank_num, bank_pin_num; |
||||
|
||||
if (check_gpio(gpio) < 0) |
||||
return -1; |
||||
|
||||
zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); |
||||
|
||||
if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) { |
||||
/* only 16 data bits in bit maskable reg */ |
||||
bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM; |
||||
reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num); |
||||
} else { |
||||
reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num); |
||||
} |
||||
|
||||
/*
|
||||
* get the 32 bit value to be written to the mask/data register where |
||||
* the upper 16 bits is the mask and lower 16 bits is the data |
||||
*/ |
||||
value = !!value; |
||||
value = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) & |
||||
((value << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK); |
||||
|
||||
writel(value, ZYNQ_GPIO_BASE_ADDRESS + reg_offset); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* gpio_direction_input - Set the direction of the specified GPIO pin as input |
||||
* @gpio: gpio pin number within the device |
||||
* |
||||
* This function uses the read-modify-write sequence to set the direction of |
||||
* the gpio pin as input. |
||||
* |
||||
* Return: -1 if invalid gpio specified, 0 if successul |
||||
*/ |
||||
int gpio_direction_input(unsigned gpio) |
||||
{ |
||||
u32 reg; |
||||
unsigned int bank_num, bank_pin_num; |
||||
|
||||
if (check_gpio(gpio) < 0) |
||||
return -1; |
||||
|
||||
zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); |
||||
|
||||
/* bank 0 pins 7 and 8 are special and cannot be used as inputs */ |
||||
if (bank_num == 0 && (bank_pin_num == 7 || bank_pin_num == 8)) |
||||
return -1; |
||||
|
||||
/* clear the bit in direction mode reg to set the pin as input */ |
||||
reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); |
||||
reg &= ~BIT(bank_pin_num); |
||||
writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* gpio_direction_output - Set the direction of the specified GPIO pin as output |
||||
* @gpio: gpio pin number within the device |
||||
* @value: value to be written to specified pin |
||||
* |
||||
* This function sets the direction of specified GPIO pin as output, configures |
||||
* the Output Enable register for the pin and uses zynq_gpio_set to set |
||||
* the value of the pin to the value specified. |
||||
* |
||||
* Return: 0 always |
||||
*/ |
||||
int gpio_direction_output(unsigned gpio, int value) |
||||
{ |
||||
u32 reg; |
||||
unsigned int bank_num, bank_pin_num; |
||||
|
||||
if (check_gpio(gpio) < 0) |
||||
return -1; |
||||
|
||||
zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num); |
||||
|
||||
/* set the GPIO pin as output */ |
||||
reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); |
||||
reg |= BIT(bank_pin_num); |
||||
writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); |
||||
|
||||
/* configure the output enable reg for the pin */ |
||||
reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); |
||||
reg |= BIT(bank_pin_num); |
||||
writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); |
||||
|
||||
/* set the state of the pin */ |
||||
gpio_set_value(gpio, value); |
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* Request a gpio before using it. |
||||
* |
||||
* NOTE: Argument 'label' is unused. |
||||
*/ |
||||
int gpio_request(unsigned gpio, const char *label) |
||||
{ |
||||
if (check_gpio(gpio) < 0) |
||||
return -1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* Reset and free the gpio after using it. |
||||
*/ |
||||
int gpio_free(unsigned gpio) |
||||
{ |
||||
return 0; |
||||
} |
@ -0,0 +1,27 @@ |
||||
/*
|
||||
* (C) Copyright 2015 Xilinx, Inc. |
||||
* |
||||
* Configuration for PicoZed |
||||
* See zynq-common.h for Zynq common configs |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef __CONFIG_ZYNQ_PICOZED_H |
||||
#define __CONFIG_ZYNQ_PICOZED_H |
||||
|
||||
#define CONFIG_SYS_SDRAM_SIZE (1024 * 1024 * 1024) |
||||
|
||||
#define CONFIG_ZYNQ_SERIAL_UART1 |
||||
#define CONFIG_ZYNQ_GEM0 |
||||
#define CONFIG_ZYNQ_GEM_PHY_ADDR0 0 |
||||
|
||||
#define CONFIG_SYS_NO_FLASH |
||||
|
||||
#define CONFIG_ZYNQ_SDHCI1 |
||||
#define CONFIG_ZYNQ_USB |
||||
#define CONFIG_ZYNQ_BOOT_FREEBSD |
||||
|
||||
#include <configs/zynq-common.h> |
||||
|
||||
#endif /* __CONFIG_ZYNQ_PICOZED_H */ |
Loading…
Reference in new issue