All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jagan Teki <jteki@openedev.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 13/18] drivers: spmi: Add support for Qualcomm SPMI bus driver
Date: Wed, 10 Feb 2016 03:07:33 +0530	[thread overview]
Message-ID: <CAD6G_RTWtBW+S-Na6YjAyqJS79+C66v69RAXAsiBCw4=qBqbBg@mail.gmail.com> (raw)
In-Reply-To: <1454878658-21046-14-git-send-email-mateusz.kulikowski@gmail.com>

On 8 February 2016 at 02:27, Mateusz Kulikowski
<mateusz.kulikowski@gmail.com> wrote:
> Support SPMI arbiter on Qualcomm Snapdragon devices.
>
> Signed-off-by: Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Tested-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Rename DM_SPMI -> SPMI
> - Rename p -> priv (in write/read)
> - Fix header ordering (again)
> - Add reviewed-by
>
> Changes in v1:
> - add binding documentation and better Kconfig help
> - Changed a bit mapping
> - Change include order
> - Use clrsetbits* where possible
> - Add one more supported dts id
> - Handle missing fields in dt properly
>
>  doc/device-tree-bindings/spmi/spmi-msm.txt |  26 ++++
>  drivers/spmi/Kconfig                       |   7 +-
>  drivers/spmi/Makefile                      |   1 +
>  drivers/spmi/spmi-msm.c                    | 189

spmi-pmic-arb.c looks fine along with binding file name as well.

+++++++++++++++++++++++++++++
>  4 files changed, 222 insertions(+), 1 deletion(-)
>  create mode 100644 doc/device-tree-bindings/spmi/spmi-msm.txt
>  create mode 100644 drivers/spmi/spmi-msm.c
>
> diff --git a/doc/device-tree-bindings/spmi/spmi-msm.txt b/doc/device-tree-bindings/spmi/spmi-msm.txt
> new file mode 100644
> index 0000000..ae47673
> --- /dev/null
> +++ b/doc/device-tree-bindings/spmi/spmi-msm.txt
> @@ -0,0 +1,26 @@
> +Qualcomm SPMI arbiter/bus driver
> +
> +This is bus driver for Qualcomm chips that use SPMI to communicate with PMICs.
> +
> +Required properties:
> +- compatible: "qcom,spmi-pmic-arb"
> +- reg: Register block adresses and sizes for various parts of device:
> +   1) PMIC arbiter channel mapping base (PMIC_ARB_REG_CHNLn)
> +   2) SPMI write command (master) registers (PMIC_ARB_CORE_SW_DEC_CHANNELS)
> +   3) SPMI read command (observer) registers (PMIC_ARB_CORE_REGISTERS_OBS)
> +
> +Optional properties (if not set by parent):
> +- #address-cells: 0x1 - childs slave ID address
> +- #size-cells: 0x1
> +
> +All PMICs should be placed as a child nodes of bus arbiter.
> +Automatic detection of childs is currently not supported.
> +
> +Example:
> +
> +spmi at 200f000 {
> +       compatible = "qcom,spmi-pmic-arb";
> +       reg = <0x200f800 0x200 0x2400000 0x400000 0x2c00000 0x400000>;
> +       #address-cells = <0x1>;
> +       #size-cells = <0x1>;
> +};
> diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
> index c70d675..8d25b45 100644
> --- a/drivers/spmi/Kconfig
> +++ b/drivers/spmi/Kconfig
> @@ -8,11 +8,16 @@ config SPMI
>           SPMI (System Power Management Interface) bus is used
>           to connect PMIC devices on various SoCs.
>
> +config SPMI_MSM
> +       boolean "Support Qualcomm SPMI bus"
> +       depends on SPMI
> +       ---help---
> +         Support SPMI bus implementation found on Qualcomm Snapdragon SoCs.
> +
>  config SPMI_SANDBOX
>         boolean "Support for Sandbox SPMI bus"
>         depends on SPMI
>         ---help---
>           Demo SPMI bus implementation. Emulates part of PM8916 as single
>            slave (0) on bus. It has 4 GPIO peripherals, pid 0xC0-0xC3.
> -
>  endmenu
> diff --git a/drivers/spmi/Makefile b/drivers/spmi/Makefile
> index 4ca65a9..c0b1220 100644
> --- a/drivers/spmi/Makefile
> +++ b/drivers/spmi/Makefile
> @@ -5,4 +5,5 @@
>  #
>
>  obj-$(CONFIG_SPMI)  += spmi-uclass.o
> +obj-$(CONFIG_SPMI_MSM) += spmi-msm.o
>  obj-$(CONFIG_SPMI_SANDBOX) += spmi-sandbox.o
> diff --git a/drivers/spmi/spmi-msm.c b/drivers/spmi/spmi-msm.c
> new file mode 100644
> index 0000000..0cef505
> --- /dev/null
> +++ b/drivers/spmi/spmi-msm.c
> @@ -0,0 +1,189 @@
> +/*
> + * Qualcomm SPMI bus driver
> + *
> + * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
> + *
> + * Loosely based on Little Kernel driver
> + *
> + * SPDX-License-Identifier:    BSD-3-Clause
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <fdtdec.h>
> +#include <asm/io.h>
> +#include <spmi/spmi.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define ARB_CHANNEL_OFFSET(n)          (0x4 * (n))
> +#define SPMI_CH_OFFSET(chnl)           ((chnl) * 0x8000)
> +
> +#define SPMI_REG_CMD0                  0x0
> +#define SPMI_REG_CONFIG                        0x4
> +#define SPMI_REG_STATUS                        0x8
> +#define SPMI_REG_WDATA                 0x10
> +#define SPMI_REG_RDATA                 0x18
> +
> +#define SPMI_CMD_OPCODE_SHIFT          27
> +#define SPMI_CMD_SLAVE_ID_SHIFT                20
> +#define SPMI_CMD_ADDR_SHIFT            12
> +#define SPMI_CMD_ADDR_OFFSET_SHIFT     4
> +#define SPMI_CMD_BYTE_CNT_SHIFT                0
> +
> +#define SPMI_CMD_EXT_REG_WRITE_LONG    0x00
> +#define SPMI_CMD_EXT_REG_READ_LONG     0x01
> +
> +#define SPMI_STATUS_DONE               0x1
> +
> +#define SPMI_MAX_CHANNELS      128
> +#define SPMI_MAX_SLAVES                16
> +#define SPMI_MAX_PERIPH                256
> +
> +struct msm_spmi_priv {
> +       phys_addr_t arb_chnl; /* ARB channel mapping base */
> +       phys_addr_t spmi_core; /* SPMI core */
> +       phys_addr_t spmi_obs; /* SPMI observer */
> +       /* SPMI channel map */
> +       uint8_t channel_map[SPMI_MAX_SLAVES][SPMI_MAX_PERIPH];
> +};
> +
> +static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off,
> +                         uint8_t val)
> +{
> +       struct msm_spmi_priv *priv = dev_get_priv(dev);
> +       unsigned channel;
> +       uint32_t reg = 0;
> +
> +       if (usid >= SPMI_MAX_SLAVES)
> +               return -EIO;
> +       if (pid >= SPMI_MAX_PERIPH)
> +               return -EIO;
> +
> +       channel = priv->channel_map[usid][pid];
> +
> +       /* Disable IRQ mode for the current channel*/
> +       writel(0x0, priv->spmi_core + SPMI_CH_OFFSET(channel) +
> +              SPMI_REG_CONFIG);
> +
> +       /* Write single byte */
> +       writel(val, priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_WDATA);
> +
> +       /* Prepare write command */
> +       reg |= SPMI_CMD_EXT_REG_WRITE_LONG << SPMI_CMD_OPCODE_SHIFT;
> +       reg |= (usid << SPMI_CMD_SLAVE_ID_SHIFT);
> +       reg |= (pid << SPMI_CMD_ADDR_SHIFT);
> +       reg |= (off << SPMI_CMD_ADDR_OFFSET_SHIFT);
> +       reg |= 1; /* byte count */
> +
> +       /* Send write command */
> +       writel(reg, priv->spmi_core + SPMI_CH_OFFSET(channel) + SPMI_REG_CMD0);
> +
> +       /* Wait till CMD DONE status */
> +       reg = 0;
> +       while (!reg) {
> +               reg = readl(priv->spmi_core + SPMI_CH_OFFSET(channel) +
> +                           SPMI_REG_STATUS);
> +       }
> +
> +       if (reg ^ SPMI_STATUS_DONE) {
> +               printf("SPMI write failure.\n");
> +               return -EIO;
> +       }
> +
> +       return 0;
> +}
> +
> +static int msm_spmi_read(struct udevice *dev, int usid, int pid, int off)
> +{
> +       struct msm_spmi_priv *priv = dev_get_priv(dev);
> +       unsigned channel;
> +       uint32_t reg = 0;
> +
> +       if (usid >= SPMI_MAX_SLAVES)
> +               return -EIO;
> +       if (pid >= SPMI_MAX_PERIPH)
> +               return -EIO;
> +
> +       channel = priv->channel_map[usid][pid];
> +
> +       /* Disable IRQ mode for the current channel*/
> +       writel(0x0, priv->spmi_obs + SPMI_CH_OFFSET(channel) + SPMI_REG_CONFIG);
> +
> +       /* Prepare read command */
> +       reg |= SPMI_CMD_EXT_REG_READ_LONG << SPMI_CMD_OPCODE_SHIFT;
> +       reg |= (usid << SPMI_CMD_SLAVE_ID_SHIFT);
> +       reg |= (pid << SPMI_CMD_ADDR_SHIFT);
> +       reg |= (off << SPMI_CMD_ADDR_OFFSET_SHIFT);
> +       reg |= 1; /* byte count */
> +
> +       /* Request read */
> +       writel(reg, priv->spmi_obs + SPMI_CH_OFFSET(channel) + SPMI_REG_CMD0);
> +
> +       /* Wait till CMD DONE status */
> +       reg = 0;
> +       while (!reg) {
> +               reg = readl(priv->spmi_obs + SPMI_CH_OFFSET(channel) +
> +                           SPMI_REG_STATUS);
> +       }
> +
> +       if (reg ^ SPMI_STATUS_DONE) {
> +               printf("SPMI read failure.\n");
> +               return -EIO;
> +       }
> +
> +       /* Read the data */
> +       return readl(priv->spmi_obs + SPMI_CH_OFFSET(channel) +
> +                    SPMI_REG_RDATA) & 0xFF;
> +}
> +
> +static struct dm_spmi_ops msm_spmi_ops = {
> +       .read = msm_spmi_read,
> +       .write = msm_spmi_write,
> +};
> +
> +static int msm_spmi_probe(struct udevice *dev)
> +{
> +       struct udevice *parent = dev->parent;
> +       struct msm_spmi_priv *priv = dev_get_priv(dev);
> +       int i;
> +
> +       priv->arb_chnl = dev_get_addr(dev);
> +       priv->spmi_core = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
> +                                                          parent->of_offset,
> +                                                          dev->of_offset,
> +                                                          "reg", 1, NULL);
> +       priv->spmi_obs = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
> +                                                         parent->of_offset,
> +                                                         dev->of_offset, "reg",
> +                                                         2, NULL);
> +       if (priv->arb_chnl == FDT_ADDR_T_NONE ||
> +           priv->spmi_core == FDT_ADDR_T_NONE ||
> +           priv->spmi_obs == FDT_ADDR_T_NONE)
> +               return -EINVAL;
> +
> +       /* Scan peripherals connected to each SPMI channel */
> +       for (i = 0; i < SPMI_MAX_CHANNELS ; i++) {
> +               uint32_t periph = readl(priv->arb_chnl + ARB_CHANNEL_OFFSET(i));
> +               uint8_t slave_id = (periph & 0xf0000) >> 16;
> +               uint8_t pid = (periph & 0xff00) >> 8;
> +
> +               priv->channel_map[slave_id][pid] = i;
> +       }
> +       return 0;
> +}
> +
> +static const struct udevice_id msm_spmi_ids[] = {
> +       { .compatible = "qcom,spmi-pmic-arb" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(msm_spmi) = {
> +       .name = "msm_spmi",
> +       .id = UCLASS_SPMI,
> +       .of_match = msm_spmi_ids,
> +       .ops = &msm_spmi_ops,
> +       .probe = msm_spmi_probe,
> +       .priv_auto_alloc_size = sizeof(struct msm_spmi_priv),
> +};
> --
> 2.5.0
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot



-- 
Jagan.

  reply	other threads:[~2016-02-09 21:37 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-07 20:57 [U-Boot] [PATCH v2 00/18] Add support for 96boards Dragonboard410C board Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 01/18] serial: Add support for Qualcomm serial port Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 02/18] gpio: Add support for Qualcomm gpio controller Mateusz Kulikowski
2016-02-09 21:25   ` Jagan Teki
2016-02-16 15:59     ` Simon Glass
2016-02-19 13:33       ` Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 03/18] mmc: Add support for Qualcomm SDHCI controller Mateusz Kulikowski
2016-02-09 21:33   ` Jagan Teki
2016-02-24 22:44     ` Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 04/18] ehci-hcd: Add init_after_reset Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 05/18] usb: ulpi: Add Kconfig options for ULPI Mateusz Kulikowski
2016-02-08 15:16   ` Marek Vasut
2016-02-07 20:57 ` [U-Boot] [PATCH v2 06/18] Migrate CONFIG_ULPI* to Kconfig Mateusz Kulikowski
2016-02-08 15:16   ` Marek Vasut
2016-02-07 20:57 ` [U-Boot] [PATCH v2 07/18] usb: Rename ehci-fsl.h to ehci-ci.h Mateusz Kulikowski
2016-02-25 15:23   ` [U-Boot] [U-Boot,v2,07/18] " Tom Rini
2016-02-07 20:57 ` [U-Boot] [PATCH v2 08/18] usb: ehci-ci: Add missing registers Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 09/18] ehci-ci.h: drop generic USBCMD fields Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 10/18] ehci: Add support for Qualcomm EHCI Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 11/18] drivers: Add SPMI bus uclass Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 12/18] spmi: Add sandbox test driver Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 13/18] drivers: spmi: Add support for Qualcomm SPMI bus driver Mateusz Kulikowski
2016-02-09 21:37   ` Jagan Teki [this message]
2016-02-19 21:02     ` Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 14/18] pmic: Add support for Qualcomm PM8916 PMIC Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 15/18] gpio: Add support for Qualcomm PM8916 gpios Mateusz Kulikowski
2016-02-09 21:44   ` Jagan Teki
2016-02-20  9:27     ` Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 16/18] arm: Add support for Qualcomm Snapdragon family Mateusz Kulikowski
2016-02-09 21:51   ` Jagan Teki
2016-02-20  9:32     ` Mateusz Kulikowski
2016-02-07 20:57 ` [U-Boot] [PATCH v2 17/18] board: Add Qualcomm Dragonboard 410C support Mateusz Kulikowski
2016-03-11 23:58   ` Daniel Glöckner
2016-03-12 21:13     ` Mateusz Kulikowski
2016-03-13 21:08       ` Daniel Glöckner
2016-02-07 20:57 ` [U-Boot] [PATCH v2 18/18] Add myself as Snapdragon and SPMI maintainer Mateusz Kulikowski
2016-02-24 23:42 ` [U-Boot] [PATCH v2 00/18] Add support for 96boards Dragonboard410C board Tom Rini
2016-03-05 22:24   ` Mateusz Kulikowski
  -- strict thread matches above, loose matches on Subject: below --
2016-01-24 20:52 Mateusz Kulikowski
2016-01-24 20:53 ` [U-Boot] [PATCH v2 13/18] drivers: spmi: Add support for Qualcomm SPMI bus driver Mateusz Kulikowski
2016-01-31 15:16   ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAD6G_RTWtBW+S-Na6YjAyqJS79+C66v69RAXAsiBCw4=qBqbBg@mail.gmail.com' \
    --to=jteki@openedev.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.