Skip to content

Commit

Permalink
[x_prj] add s900 pinctrl driver.
Browse files Browse the repository at this point in the history
  • Loading branch information
pengoor committed Jul 5, 2016
1 parent 5ce3bb6 commit 7340ec6
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 40 deletions.
18 changes: 18 additions & 0 deletions arch/arm/dts/s900-bubblegum-pinctrl.dtsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2015 wowotech
*
* wowo<wowo@wowotech.net>
*
* SPDX-License-Identifier: GPL-2.0+
*/

#include "s900.dtsi"

/ {
pinctrl@e01b0000 {
/* actions,pins = <reg, offset, mask, valude>, ...*/
pinctrl_serial5: serial5 {
actions,pins = <0x0044 23 0x3f 0xc>;
};
};
};
17 changes: 14 additions & 3 deletions arch/arm/dts/s900-bubblegum.dts
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
/*
* Copyright (c) 2015 Actions Semi Co., Ltd.
* Copyright (c) 2015 wowotech
*
* wowo<wowo@wowotech.net>
*
* SPDX-License-Identifier: GPL-2.0+
*/
/dts-v1/;

#include "s900.dtsi"
#include "s900-bubblegum-pinctrl.dtsi"

/ {
uart5: serial@e012a000 {
compatible = "actions,s900-serial";
pinctrl@e01b0000 {
u-boot,dm-pre-reloc;
};

serial5: serial@e012a000 {
u-boot,dm-pre-reloc;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_serial5>;
};

};
22 changes: 22 additions & 0 deletions arch/arm/dts/s900.dtsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2015 wowotech
*
* wowo<wowo@wowotech.net>
*
* SPDX-License-Identifier: GPL-2.0+
*/

/ {
#address-cells = <2>;
#size-cells = <2>;

serial5: serial@e012a000 {
compatible = "actions,s900-serial";
reg = <0 0xe012a000 0 0x1000>;
};

pinctrl@e01b0000 {
compatible = "actions,s900-pinctrl";
reg = <0 0xe01b0000 0 0x1000>;
};
};
15 changes: 8 additions & 7 deletions configs/bubblegum_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,7 @@ CONFIG_OF_CONTROL=y
# CONFIG_SPL_OF_CONTROL is not set
CONFIG_OF_SEPARATE=y
# CONFIG_OF_EMBED is not set
CONFIG_NET=y
# CONFIG_NET_RANDOM_ETHADDR is not set
# CONFIG_NETCONSOLE is not set
CONFIG_NET_TFTP_VARS=y
# CONFIG_NET is not set

#
# Device Drivers
Expand All @@ -338,7 +335,7 @@ CONFIG_OF_TRANSLATE=y
# CONFIG_ADC_EXYNOS is not set
# CONFIG_ADC_SANDBOX is not set
# CONFIG_BLK is not set
CONFIG_DISK=y
# CONFIG_DISK is not set
# CONFIG_BLOCK_CACHE is not set

#
Expand Down Expand Up @@ -432,7 +429,6 @@ CONFIG_DISK=y
# CONFIG_SPI_FLASH is not set
# CONFIG_DM_ETH is not set
# CONFIG_PHYLIB is not set
# CONFIG_NETDEVICES is not set

#
# PCI
Expand All @@ -442,7 +438,12 @@ CONFIG_DISK=y
#
# Pin controllers
#
# CONFIG_PINCTRL is not set
CONFIG_PINCTRL=y
CONFIG_PINCTRL_FULL=y
# CONFIG_PINCTRL_GENERIC is not set
# CONFIG_ROCKCHIP_PINCTRL is not set
# CONFIG_ROCKCHIP_3036_PINCTRL is not set
CONFIG_OWL_PINCTRL=y

#
# Power
Expand Down
5 changes: 5 additions & 0 deletions drivers/pinctrl/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ config PIC32_PINCTRL
by a device tree node which contains both GPIO defintion and pin control
functions.

config OWL_PINCTRL
bool "Actions pin control driver for OWL soc"
depends on DM
help
Support pin multiplexing control on Actions OWL SoCs.
endif

source "drivers/pinctrl/nxp/Kconfig"
Expand Down
2 changes: 2 additions & 0 deletions drivers/pinctrl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o

obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_PIC32_PINCTRL) += pinctrl_pic32.o

obj-$(CONFIG_OWL_PINCTRL) += pinctrl-owl.o
78 changes: 78 additions & 0 deletions drivers/pinctrl/pinctrl-owl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2015 wowotech
*
* wowo<wowo@wowotech.net>
*
* SPDX-License-Identifier: GPL-2.0+
*/

#define DEBUGX

#include <common.h>
#include <asm/io.h>
#include <dm/device.h>
#include <dm/pinctrl.h>

DECLARE_GLOBAL_DATA_PTR;

struct owl_pinctrl_priv {
fdt_addr_t base; /* register address */
};

static int owl_pinctrl_set_state_simple(struct udevice *dev,
struct udevice *periph)
{
int entry, count, i;
uint32_t cell[20];
struct owl_pinctrl_priv *priv = dev_get_priv(dev);

entry = fdtdec_lookup_phandle(gd->fdt_blob, periph->of_offset,
"pinctrl-0");
if (entry < 0)
return -1;

count = fdtdec_get_int_array_count(gd->fdt_blob, entry, "actions,pins",
cell, ARRAY_SIZE(cell));
if (count < 4)
return -1;

for (i = 0; i < count / 4; i += 4)
clrsetbits_le32(priv->base + cell[i],
cell[i + 2] << cell[i + 1],
cell[i + 3] << cell[i + 1]);

return 0;
}

static const struct pinctrl_ops owl_pinctrl_ops = {
.set_state_simple = owl_pinctrl_set_state_simple,
};

static int owl_pinctrl_probe(struct udevice *dev)
{
struct owl_pinctrl_priv *priv = dev_get_priv(dev);

priv->base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
if (priv->base == FDT_ADDR_T_NONE)
return -1;

debug("%s: base is 0x%llx\n", __func__, priv->base);

return 0;
}


static const struct udevice_id owl_pinctrl_match[] = {
{ .compatible = "actions,s900-pinctrl" },
{ /* sentinel */ }
};

U_BOOT_DRIVER(owl_pinctrl) = {
.name = "owl_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = owl_pinctrl_match,
.probe = owl_pinctrl_probe,
.ops = &owl_pinctrl_ops,
.flags = DM_FLAG_PRE_RELOC,
.priv_auto_alloc_size = sizeof(struct owl_pinctrl_priv),
};
54 changes: 26 additions & 28 deletions drivers/serial/serial_owl.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include <fdtdec.h>
#include <serial.h>

struct owl_serial_priv {
fdt_addr_t base; /* register address */
};

DECLARE_GLOBAL_DATA_PTR;

/* TODO, we need pinmux, device tree, clock framework, etc. */
Expand All @@ -32,12 +36,6 @@ DECLARE_GLOBAL_DATA_PTR;
#define UART2_BASE (0xE0124000)
#define UART5_BASE (0xE012a000)

#ifdef USING_UART2
#define UART_BASE UART2_BASE
#else
#define UART_BASE UART5_BASE
#endif

/* UART Register offset */
#define UART_CTL (0x0)
#define UART_RXDAT (0x4)
Expand Down Expand Up @@ -71,6 +69,7 @@ DECLARE_GLOBAL_DATA_PTR;
int owl_serial_setbrg(struct udevice *dev, int baudrate)
{
int divider;
struct owl_serial_priv *priv = dev_get_priv(dev);

divider = HOSC_FREQ / (baudrate * 8);
if (divider > 0)
Expand All @@ -81,36 +80,41 @@ int owl_serial_setbrg(struct udevice *dev, int baudrate)
/*
* 8N1
*/
clrsetbits_le32(UART_BASE + UART_CTL, UART_CTL_DATA_WIDTH,
clrsetbits_le32(priv->base + UART_CTL, UART_CTL_DATA_WIDTH,
UART_DATA_WIDTH_8);
clrsetbits_le32(UART_BASE + UART_CTL, UART_CTL_PARITY,
clrsetbits_le32(priv->base + UART_CTL, UART_CTL_PARITY,
UART_PARITY_NONE);
clrbits_le32(UART_BASE + UART_CTL, UART_CTL_STOP);
clrbits_le32(priv->base + UART_CTL, UART_CTL_STOP);

return 0;
}

static int owl_serial_getc(struct udevice *dev)
{
if (readl(UART_BASE + UART_STAT) & UART_STAT_RFEM)
struct owl_serial_priv *priv = dev_get_priv(dev);

if (readl(priv->base + UART_STAT) & UART_STAT_RFEM)
return -EAGAIN;

return (int)(readl(UART_BASE + UART_RXDAT));
return (int)(readl(priv->base + UART_RXDAT));
}

static int owl_serial_putc(struct udevice *dev, const char ch)
{
if (readl(UART_BASE + UART_STAT) & UART_STAT_TFFU)
struct owl_serial_priv *priv = dev_get_priv(dev);

if (readl(priv->base + UART_STAT) & UART_STAT_TFFU)
return -EAGAIN;

writel(ch, UART_BASE + UART_TXDAT);
writel(ch, priv->base + UART_TXDAT);

return 0;
}

static int owl_serial_pending(struct udevice *dev, bool input)
{
unsigned int stat = readl(UART_BASE + UART_STAT);
struct owl_serial_priv *priv = dev_get_priv(dev);
unsigned int stat = readl(priv->base + UART_STAT);

if (input)
return !(stat & UART_STAT_RFEM);
Expand All @@ -121,17 +125,14 @@ static int owl_serial_pending(struct udevice *dev, bool input)
extern void bubblegum_early_debug(int debug_code);
static int owl_serial_probe(struct udevice *dev)
{
bubblegum_early_debug(4);
struct owl_serial_priv *priv = dev_get_priv(dev);

/* pinmux */
#ifdef USING_UART2
setbits_le32(MFP_CTL1, 1 << 22);
#else
/* uart5, GPIOA25/GPIOA27 */
clrsetbits_le32(MFP_CTL1, 0x3f << 23, 0xc << 23);
#endif
priv->base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
if (priv->base == FDT_ADDR_T_NONE)
return -1;

debug("%s: base is 0x%llx\n", __func__, priv->base);

bubblegum_early_debug(5);

/* device clock enable */
#ifdef USING_UART2
Expand All @@ -140,22 +141,18 @@ static int owl_serial_probe(struct udevice *dev)
setbits_le32(CMU_DEVCLKEN1, 1 << 21); /* uart5 */
#endif

bubblegum_early_debug(6);

/* reset de-assert */
#ifdef USING_UART2
setbits_le32(CMU_DEVRST1, 1 << 7);
#else
setbits_le32(CMU_DEVRST1, 1 << 17);
#endif

bubblegum_early_debug(7);

/* set default baudrate and enable UART */
owl_serial_setbrg(dev, 115200);

/* enable uart */
setbits_le32(UART_BASE + UART_CTL, UART_CTL_EN);
setbits_le32(priv->base + UART_CTL, UART_CTL_EN);

bubblegum_early_debug(8);
return 0;
Expand All @@ -180,4 +177,5 @@ U_BOOT_DRIVER(serial_owl) = {
.probe = owl_serial_probe,
.ops = &owl_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
.priv_auto_alloc_size = sizeof(struct owl_serial_priv),
};
4 changes: 2 additions & 2 deletions include/configs/bubblegum.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#ifndef __BUBBLEGUM_H
#define __BUBBLEGUM_H

#define DEBUG
#define DEBUGX

/*
* u-boot SPL definitions, which is resided in SRAM
Expand Down Expand Up @@ -52,7 +52,7 @@
#define CONFIG_ENV_SIZE 0x1000 /* 4K Bytes */

/* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN (16 * 1024 * 1024 + CONFIG_ENV_SIZE)
#define CONFIG_SYS_MALLOC_LEN (16 * 1024 + CONFIG_ENV_SIZE)

#define CONFIG_SYS_CBSIZE 512 /* Console I/O Buffer Size */
#define CONFIG_SYS_MAXARGS 16 /* max command args */
Expand Down

0 comments on commit 7340ec6

Please sign in to comment.