mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-20 08:58:52 +09:00
![Robert Marko](/assets/img/avatar_default.png)
This introduces initial support for the popular Qualcomm IPQ40x8 and IPQ40x9 WiSoC series. IPQ40xx series have 4x Cortex A7 ARM-v7A cores. Supported are: IPQ4018, IPQ4019, IPQ4028 and IPQ4029. IPQ40x8 and IPQ40x9 use the same cores, but differ in addressable RAM size (1GB for IPQ40x9 and 256MB for IPQ40x8) and supported peripherals (IPQ40x8 lacks RGMII, LCD controller and EMMC/SDHCI controllers). IQP4028/IPQ4029 models differ from IPQ4018/IPQ4019 only by their rated temperatures rates with IPQ402X models being rated for wider temperature ranges. Initially this supports: * Simple clock driver (Only for UART1 now, will be extended) * Pinctrl driver (Supports UARTX and GPIO now, will be extended) * GPIOs already supported by msm_gpio driver with updates * UARTs already supported by serial_msm driver with updates Further peripherals will come in later patches. Signed-off-by: Robert Marko <robert.marko@sartura.hr>
138 lines
3.5 KiB
C
138 lines
3.5 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* TLMM driver for Qualcomm IPQ40xx
|
|
*
|
|
* (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
|
|
*
|
|
* Copyright (c) 2020 Sartura Ltd.
|
|
*
|
|
* Author: Robert Marko <robert.marko@sartura.hr>
|
|
*
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <dm.h>
|
|
#include <errno.h>
|
|
#include <asm/io.h>
|
|
#include <dm/pinctrl.h>
|
|
#include <linux/bitops.h>
|
|
#include "pinctrl-snapdragon.h"
|
|
|
|
struct msm_pinctrl_priv {
|
|
phys_addr_t base;
|
|
struct msm_pinctrl_data *data;
|
|
};
|
|
|
|
#define GPIO_CONFIG_OFFSET(x) ((x) * 0x1000)
|
|
#define TLMM_GPIO_PULL_MASK GENMASK(1, 0)
|
|
#define TLMM_FUNC_SEL_MASK GENMASK(5, 2)
|
|
#define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6)
|
|
#define TLMM_GPIO_DISABLE BIT(9)
|
|
|
|
static const struct pinconf_param msm_conf_params[] = {
|
|
{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 2 },
|
|
{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
|
|
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 2 },
|
|
};
|
|
|
|
static int msm_get_functions_count(struct udevice *dev)
|
|
{
|
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
|
|
|
return priv->data->functions_count;
|
|
}
|
|
|
|
static int msm_get_pins_count(struct udevice *dev)
|
|
{
|
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
|
|
|
return priv->data->pin_count;
|
|
}
|
|
|
|
static const char *msm_get_function_name(struct udevice *dev,
|
|
unsigned int selector)
|
|
{
|
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
|
|
|
return priv->data->get_function_name(dev, selector);
|
|
}
|
|
|
|
static int msm_pinctrl_probe(struct udevice *dev)
|
|
{
|
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
|
|
|
priv->base = devfdt_get_addr(dev);
|
|
priv->data = (struct msm_pinctrl_data *)dev->driver_data;
|
|
|
|
return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
|
|
}
|
|
|
|
static const char *msm_get_pin_name(struct udevice *dev, unsigned int selector)
|
|
{
|
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
|
|
|
return priv->data->get_pin_name(dev, selector);
|
|
}
|
|
|
|
static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
|
|
unsigned int func_selector)
|
|
{
|
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
|
|
|
clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
|
|
TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE,
|
|
priv->data->get_function_mux(func_selector) << 2);
|
|
return 0;
|
|
}
|
|
|
|
static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
|
|
unsigned int param, unsigned int argument)
|
|
{
|
|
struct msm_pinctrl_priv *priv = dev_get_priv(dev);
|
|
|
|
switch (param) {
|
|
case PIN_CONFIG_DRIVE_STRENGTH:
|
|
clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
|
|
TLMM_DRV_STRENGTH_MASK, argument << 6);
|
|
break;
|
|
case PIN_CONFIG_BIAS_DISABLE:
|
|
clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
|
|
TLMM_GPIO_PULL_MASK);
|
|
break;
|
|
case PIN_CONFIG_BIAS_PULL_UP:
|
|
clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
|
|
TLMM_GPIO_PULL_MASK, argument);
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct pinctrl_ops msm_pinctrl_ops = {
|
|
.get_pins_count = msm_get_pins_count,
|
|
.get_pin_name = msm_get_pin_name,
|
|
.set_state = pinctrl_generic_set_state,
|
|
.pinmux_set = msm_pinmux_set,
|
|
.pinconf_num_params = ARRAY_SIZE(msm_conf_params),
|
|
.pinconf_params = msm_conf_params,
|
|
.pinconf_set = msm_pinconf_set,
|
|
.get_functions_count = msm_get_functions_count,
|
|
.get_function_name = msm_get_function_name,
|
|
};
|
|
|
|
static const struct udevice_id msm_pinctrl_ids[] = {
|
|
{ .compatible = "qcom,tlmm-ipq4019", .data = (ulong)&ipq4019_data },
|
|
{ }
|
|
};
|
|
|
|
U_BOOT_DRIVER(pinctrl_snapdraon) = {
|
|
.name = "pinctrl_msm",
|
|
.id = UCLASS_PINCTRL,
|
|
.of_match = msm_pinctrl_ids,
|
|
.priv_auto_alloc_size = sizeof(struct msm_pinctrl_priv),
|
|
.ops = &msm_pinctrl_ops,
|
|
.probe = msm_pinctrl_probe,
|
|
};
|