* [PATCH V5] ST SPEAr: PCIE gadget suppport
From: pratyush @ 2011-02-21 8:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298276013-14716-1-git-send-email-y>
Sorry, Please discard this patch.
Regards
Pratyush
On 2/21/2011 1:43 PM, y wrote:
> From: Pratyush Anand <pratyush.anand@st.com>
>
> This is a configurable gadget. can be configured by configfs interface. Any
> IP available at PCIE bus can be programmed to be used by host
> controller.It supoorts both INTX and MSI.
> By default, gadget is configured for INTX and SYSRAM1 is mapped to BAR0
> with size 0x1000
>
> Changes since V4:
> - All documentation related comments incorporated
>
> Changes since V3:
> - support for multiple instances of such device
> - changes to minimzie portability issue on 64 bit machine
> - unnecessary typecast removed
> - sysfs_streq used in place of complex code
>
> Changes since V2:
> - driver has been moved from sysfs to configfs
> - Documentation/ABI directory has also been updated
> - typo error in documenation has been corrected
> - clk value is checked after encapsulating by IS_ERR
>
> Changes since V1:
> - __iomem added for register addresses
> - kerneldoc comment removed whereever not required.
> - help node moved from sysfs to documentation/misc-devices
> - strict_strtoul used instead of sscanf
>
> Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
> ---
> .../ABI/testing/configfs-spear-pcie-gadget | 30 +
> Documentation/misc-devices/spear-pcie-gadget.txt | 129 +++
> drivers/misc/Kconfig | 10 +
> drivers/misc/Makefile | 1 +
> drivers/misc/spear13xx_pcie_gadget.c | 908 ++++++++++++++++++++
> 5 files changed, 1078 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/ABI/testing/configfs-spear-pcie-gadget
> create mode 100644 Documentation/misc-devices/spear-pcie-gadget.txt
> create mode 100644 drivers/misc/spear13xx_pcie_gadget.c
>
> diff --git a/Documentation/ABI/testing/configfs-spear-pcie-gadget b/Documentation/ABI/testing/configfs-spear-pcie-gadget
> new file mode 100644
> index 0000000..29593d0
> --- /dev/null
> +++ b/Documentation/ABI/testing/configfs-spear-pcie-gadget
> @@ -0,0 +1,30 @@
> +What: /config/pcie-gadget
> +Date: Feb 2011
> +KernelVersion: 2.6.37
> +Contact: Pratyush Anand <pratyush.anand@st.com>
> +Description:
> +
> + Interface is used to configure selected dual mode PCIe controller
> + as device and then program its various registers to configure it
> + as a particular device type.
> + This interfaces can be used to show spear's PCIe device capability.
> +
> + Nodes are only visible when configfs is mounted. To mount configfs
> + in /config directory use:
> + # mount -t configfs none /config/
> +
> + /config/pcie-gadget/
> + link ... used to enable ltssm and read its status.
> + int_type ...used to configure and read type of supported
> + interrupt
> + no_of_msi ... used to configure number of MSI vector needed and
> + to read no of MSI granted.
> + inta ... write 1 to assert INTA and 0 to de-assert.
> + send_msi ... write MSI vector to be sent.
> + vendor_id ... used to write and read vendor id (hex)
> + device_id ... used to write and read device id (hex)
> + bar0_size ... used to write and read bar0_size
> + bar0_address ... used to write and read bar0 mapped area in hex.
> + bar0_rw_offset ... used to write and read offset of bar0 where
> + bar0_data will be written or read.
> + bar0_data ... used to write and read data at bar0_rw_offset.
> diff --git a/Documentation/misc-devices/spear-pcie-gadget.txt b/Documentation/misc-devices/spear-pcie-gadget.txt
> new file mode 100644
> index 0000000..7b86b80
> --- /dev/null
> +++ b/Documentation/misc-devices/spear-pcie-gadget.txt
> @@ -0,0 +1,129 @@
> +Spear PCIe Gadget Driver:
> +
> +Author
> +=============
> +Pratyush Anand (pratyush.anand at st.com)
> +
> +Location
> +============
> +driver/misc/spear13xx_pcie_gadget.c
> +
> +Supported Chip:
> +===================
> +SPEAr1300
> +SPEAr1310
> +
> +Menuconfig option:
> +==========================
> +Device Drivers
> + Misc devices
> + PCIe gadget support for SPEAr13XX platform
> +purpose
> +===========
> +This driver has several nodes which can be read/written by configfs interface.
> +Its main purpose is to configure selected dual mode PCIe controller as device
> +and then program its various registers to configure it as a particular device
> +type. This driver can be used to show spear's PCIe device capability.
> +
> +Description of different nodes:
> +=================================
> +
> +read behavior of nodes:
> +------------------------------
> +link :gives ltssm status.
> +int_type :type of supported interrupt
> +no_of_msi :zero if MSI is not enabled by host. A positive value is the
> + number of MSI vector granted.
> +vendor_id :returns programmed vendor id (hex)
> +device_id :returns programmed device id(hex)
> +bar0_size: :returns size of bar0 in hex.
> +bar0_address :returns address of bar0 mapped area in hex.
> +bar0_rw_offset :returns offset of bar0 for which bar0_data will return value.
> +bar0_data :returns data at bar0_rw_offset.
> +
> +write behavior of nodes:
> +------------------------------
> +link :write UP to enable ltsmm DOWN to disable
> +int_type :write interrupt type to be configured and (int_type could be
> + INTA, MSI or NO_INT). Select MSI only when you have programmed
> + no_of_msi node.
> +no_of_msi :number of MSI vector needed.
> +inta :write 1 to assert INTA and 0 to de-assert.
> +send_msi :write MSI vector to be sent.
> +vendor_id :write vendor id(hex) to be programmed.
> +device_id :write device id(hex) to be programmed.
> +bar0_size :write size of bar0 in hex. default bar0 size is 1000 (hex)
> + bytes.
> +bar0_address :write address of bar0 mapped area in hex. (default mapping of
> + bar0 is SYSRAM1(E0800000). Always program bar size before bar
> + address. Kernel might modify bar size and address for alignment, so
> + read back bar size and address after writing to cross check.
> +bar0_rw_offset :write offset of bar0 for which bar0_data will write value.
> +bar0_data :write data to be written at bar0_rw_offset.
> +
> +Node programming example
> +===========================
> +Program all PCIe registers in such a way that when this device is connected
> +to the PCIe host, then host sees this device as 1MB RAM.
> +#mount -t configfs none /Config
> +# cd /config/pcie_gadget/
> +Now you have all the nodes in this directory.
> +program vendor id as 0x104a
> +# echo 104A >> vendor_id
> +
> +program device id as 0xCD80
> +# echo CD80 >> device_id
> +
> +program BAR0 size as 1MB
> +# echo 100000 >> bar0_size
> +
> +check for programmed bar0 size
> +# cat bar0_size
> +
> +Program BAR0 Address as DDR (0x2100000). This is the physical address of
> +memory, which is to be made visible to PCIe host. Similarly any other peripheral
> +can also be made visible to PCIe host. E.g., if you program base address of UART
> +as BAR0 address then when this device will be connected to a host, it will be
> +visible as UART.
> +# echo 2100000 >> bar0_address
> +
> +program interrupt type : INTA
> +# echo INTA >> int_type
> +
> +go for link up now.
> +# echo UP >> link
> +
> +It will have to be insured that, once link up is done on gadget, then only host
> +is initialized and start to search PCIe devices on its port.
> +
> +/*wait till link is up*/
> +# cat link
> +wait till it returns UP.
> +
> +To assert INTA
> +# echo 1 >> inta
> +
> +To de-assert INTA
> +# echo 0 >> inta
> +
> +if MSI is to be used as interrupt, program no of msi vector needed (say4)
> +# echo 4 >> no_of_msi
> +
> +select MSI as interrupt type
> +# echo MSI >> int_type
> +
> +go for link up now
> +# echo UP >> link
> +
> +wait till link is up
> +# cat link
> +An application can repetitively read this node till link is found UP. It can
> +sleep between two read.
> +
> +wait till msi is enabled
> +# cat no_of_msi
> +Should return 4 (number of requested MSI vector)
> +
> +to send msi vector 2
> +# echo 2 >> send_msi
> +#cd -
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 4d073f1..dea052d 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -394,6 +394,16 @@ config DS1682
> This driver can also be built as a module. If so, the module
> will be called ds1682.
>
> +config SPEAR13XX_PCIE_GADGET
> + bool "PCIe gadget support for SPEAr13XX platform"
> + depends on ARCH_SPEAR13XX
> + default n
> + help
> + This option enables gadget support for PCIe controller. If
> + board file defines any controller as PCIe endpoint then a sysfs
> + entry will be created for that controller. User can use these
> + sysfs node to configure PCIe EP as per his requirements.
> +
> config TI_DAC7512
> tristate "Texas Instruments DAC7512"
> depends on SPI && SYSFS
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 98009cc..c489536 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -37,6 +37,7 @@ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/
> obj-$(CONFIG_HMC6352) += hmc6352.o
> obj-y += eeprom/
> obj-y += cb710/
> +obj-$(CONFIG_SPEAR13XX_PCIE_GADGET) += spear13xx_pcie_gadget.o
> obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o
> obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
> obj-$(CONFIG_PCH_PHUB) += pch_phub.o
> diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c
> new file mode 100644
> index 0000000..ec3b8c9
> --- /dev/null
> +++ b/drivers/misc/spear13xx_pcie_gadget.c
> @@ -0,0 +1,908 @@
> +/*
> + * drivers/misc/spear13xx_pcie_gadget.c
> + *
> + * Copyright (C) 2010 ST Microelectronics
> + * Pratyush Anand<pratyush.anand@st.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/slab.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/pci_regs.h>
> +#include <linux/configfs.h>
> +#include <mach/pcie.h>
> +#include <mach/misc_regs.h>
> +
> +#define IN0_MEM_SIZE (200 * 1024 * 1024 - 1)
> +/* In current implementation address translation is done using IN0 only.
> + * So IN1 start address and IN0 end address has been kept same
> +*/
> +#define IN1_MEM_SIZE (0 * 1024 * 1024 - 1)
> +#define IN_IO_SIZE (20 * 1024 * 1024 - 1)
> +#define IN_CFG0_SIZE (12 * 1024 * 1024 - 1)
> +#define IN_CFG1_SIZE (12 * 1024 * 1024 - 1)
> +#define IN_MSG_SIZE (12 * 1024 * 1024 - 1)
> +/* Keep default BAR size as 4K*/
> +/* AORAM would be mapped by default*/
> +#define INBOUND_ADDR_MASK (SPEAR13XX_SYSRAM1_SIZE - 1)
> +
> +#define INT_TYPE_NO_INT 0
> +#define INT_TYPE_INTX 1
> +#define INT_TYPE_MSI 2
> +struct spear_pcie_gadget_config {
> + void __iomem *base;
> + void __iomem *va_app_base;
> + void __iomem *va_dbi_base;
> + char int_type[10];
> + ulong requested_msi;
> + ulong configured_msi;
> + ulong bar0_size;
> + ulong bar0_rw_offset;
> + void __iomem *va_bar0_address;
> +};
> +
> +struct pcie_gadget_target {
> + struct configfs_subsystem subsys;
> + struct spear_pcie_gadget_config config;
> +};
> +
> +struct pcie_gadget_target_attr {
> + struct configfs_attribute attr;
> + ssize_t (*show)(struct spear_pcie_gadget_config *config,
> + char *buf);
> + ssize_t (*store)(struct spear_pcie_gadget_config *config,
> + const char *buf,
> + size_t count);
> +};
> +
> +static void enable_dbi_access(struct pcie_app_reg __iomem *app_reg)
> +{
> + /* Enable DBI access */
> + writel(readl(&app_reg->slv_armisc) | (1 << AXI_OP_DBI_ACCESS_ID),
> + &app_reg->slv_armisc);
> + writel(readl(&app_reg->slv_awmisc) | (1 << AXI_OP_DBI_ACCESS_ID),
> + &app_reg->slv_awmisc);
> +
> +}
> +
> +static void disable_dbi_access(struct pcie_app_reg __iomem *app_reg)
> +{
> + /* disable DBI access */
> + writel(readl(&app_reg->slv_armisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
> + &app_reg->slv_armisc);
> + writel(readl(&app_reg->slv_awmisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
> + &app_reg->slv_awmisc);
> +
> +}
> +
> +static void spear_dbi_read_reg(struct spear_pcie_gadget_config *config,
> + int where, int size, u32 *val)
> +{
> + struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> + ulong va_address;
> +
> + /* Enable DBI access */
> + enable_dbi_access(app_reg);
> +
> + va_address = (ulong)config->va_dbi_base + (where & ~0x3);
> +
> + *val = readl(va_address);
> +
> + if (size == 1)
> + *val = (*val >> (8 * (where & 3))) & 0xff;
> + else if (size == 2)
> + *val = (*val >> (8 * (where & 3))) & 0xffff;
> +
> + /* Disable DBI access */
> + disable_dbi_access(app_reg);
> +}
> +
> +static void spear_dbi_write_reg(struct spear_pcie_gadget_config *config,
> + int where, int size, u32 val)
> +{
> + struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> + ulong va_address;
> +
> + /* Enable DBI access */
> + enable_dbi_access(app_reg);
> +
> + va_address = (ulong)config->va_dbi_base + (where & ~0x3);
> +
> + if (size == 4)
> + writel(val, va_address);
> + else if (size == 2)
> + writew(val, va_address + (where & 2));
> + else if (size == 1)
> + writeb(val, va_address + (where & 3));
> +
> + /* Disable DBI access */
> + disable_dbi_access(app_reg);
> +}
> +
> +#define PCI_FIND_CAP_TTL 48
> +
> +static int pci_find_own_next_cap_ttl(struct spear_pcie_gadget_config *config,
> + u32 pos, int cap, int *ttl)
> +{
> + u32 id;
> +
> + while ((*ttl)--) {
> + spear_dbi_read_reg(config, pos, 1, &pos);
> + if (pos < 0x40)
> + break;
> + pos &= ~3;
> + spear_dbi_read_reg(config, pos + PCI_CAP_LIST_ID, 1, &id);
> + if (id == 0xff)
> + break;
> + if (id == cap)
> + return pos;
> + pos += PCI_CAP_LIST_NEXT;
> + }
> + return 0;
> +}
> +
> +static int pci_find_own_next_cap(struct spear_pcie_gadget_config *config,
> + u32 pos, int cap)
> +{
> + int ttl = PCI_FIND_CAP_TTL;
> +
> + return pci_find_own_next_cap_ttl(config, pos, cap, &ttl);
> +}
> +
> +static int pci_find_own_cap_start(struct spear_pcie_gadget_config *config,
> + u8 hdr_type)
> +{
> + u32 status;
> +
> + spear_dbi_read_reg(config, PCI_STATUS, 2, &status);
> + if (!(status & PCI_STATUS_CAP_LIST))
> + return 0;
> +
> + switch (hdr_type) {
> + case PCI_HEADER_TYPE_NORMAL:
> + case PCI_HEADER_TYPE_BRIDGE:
> + return PCI_CAPABILITY_LIST;
> + case PCI_HEADER_TYPE_CARDBUS:
> + return PCI_CB_CAPABILITY_LIST;
> + default:
> + return 0;
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * Tell if a device supports a given PCI capability.
> + * Returns the address of the requested capability structure within the
> + * device's PCI configuration space or 0 in case the device does not
> + * support it. Possible values for @cap:
> + *
> + * %PCI_CAP_ID_PM Power Management
> + * %PCI_CAP_ID_AGP Accelerated Graphics Port
> + * %PCI_CAP_ID_VPD Vital Product Data
> + * %PCI_CAP_ID_SLOTID Slot Identification
> + * %PCI_CAP_ID_MSI Message Signalled Interrupts
> + * %PCI_CAP_ID_CHSWP CompactPCI HotSwap
> + * %PCI_CAP_ID_PCIX PCI-X
> + * %PCI_CAP_ID_EXP PCI Express
> + */
> +static int pci_find_own_capability(struct spear_pcie_gadget_config *config,
> + int cap)
> +{
> + u32 pos;
> + u32 hdr_type;
> +
> + spear_dbi_read_reg(config, PCI_HEADER_TYPE, 1, &hdr_type);
> +
> + pos = pci_find_own_cap_start(config, hdr_type);
> + if (pos)
> + pos = pci_find_own_next_cap(config, pos, cap);
> +
> + return pos;
> +}
> +
> +static irqreturn_t spear_pcie_gadget_irq(int irq, void *dev_id)
> +{
> + return 0;
> +}
> +
> +/*
> + * configfs interfaces show/store functions
> + */
> +static ssize_t pcie_gadget_show_link(
> + struct spear_pcie_gadget_config *config,
> + char *buf)
> +{
> + struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +
> + if (readl(&app_reg->app_status_1) & ((u32)1 << XMLH_LINK_UP_ID))
> + return sprintf(buf, "UP");
> + else
> + return sprintf(buf, "DOWN");
> +}
> +
> +static ssize_t pcie_gadget_store_link(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +
> + if (sysfs_streq(buf, "UP"))
> + writel(readl(&app_reg->app_ctrl_0) | (1 << APP_LTSSM_ENABLE_ID),
> + &app_reg->app_ctrl_0);
> + else if (sysfs_streq(buf, "DOWN"))
> + writel(readl(&app_reg->app_ctrl_0)
> + & ~(1 << APP_LTSSM_ENABLE_ID),
> + &app_reg->app_ctrl_0);
> + else
> + return -EINVAL;
> + return count;
> +}
> +
> +static ssize_t pcie_gadget_show_int_type(
> + struct spear_pcie_gadget_config *config,
> + char *buf)
> +{
> + return sprintf(buf, "%s", config->int_type);
> +}
> +
> +static ssize_t pcie_gadget_store_int_type(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + u32 cap, vec, flags;
> + ulong vector;
> +
> + if (sysfs_streq(buf, "INTA"))
> + spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
> +
> + else if (sysfs_streq(buf, "MSI")) {
> + vector = config->requested_msi;
> + vec = 0;
> + while (vector > 1) {
> + vector /= 2;
> + vec++;
> + }
> + spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 0);
> + cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
> + spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
> + flags &= ~PCI_MSI_FLAGS_QMASK;
> + flags |= vec << 1;
> + spear_dbi_write_reg(config, cap + PCI_MSI_FLAGS, 1, flags);
> + } else
> + return -EINVAL;
> +
> + strcpy(config->int_type, buf);
> +
> + return count;
> +}
> +
> +static ssize_t pcie_gadget_show_no_of_msi(
> + struct spear_pcie_gadget_config *config,
> + char *buf)
> +{
> + struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> + u32 cap, vec, flags;
> + ulong vector;
> +
> + if ((readl(&app_reg->msg_status) & (1 << CFG_MSI_EN_ID))
> + != (1 << CFG_MSI_EN_ID))
> + vector = 0;
> + else {
> + cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
> + spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
> + flags &= ~PCI_MSI_FLAGS_QSIZE;
> + vec = flags >> 4;
> + vector = 1;
> + while (vec--)
> + vector *= 2;
> + }
> + config->configured_msi = vector;
> +
> + return sprintf(buf, "%lu", vector);
> +}
> +
> +static ssize_t pcie_gadget_store_no_of_msi(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + if (strict_strtoul(buf, 0, &config->requested_msi))
> + return -EINVAL;
> + if (config->requested_msi > 32)
> + config->requested_msi = 32;
> +
> + return count;
> +}
> +
> +static ssize_t pcie_gadget_store_inta(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> + ulong en;
> +
> + if (strict_strtoul(buf, 0, &en))
> + return -EINVAL;
> +
> + if (en)
> + writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID),
> + &app_reg->app_ctrl_0);
> + else
> + writel(readl(&app_reg->app_ctrl_0) & ~(1 << SYS_INT_ID),
> + &app_reg->app_ctrl_0);
> +
> + return count;
> +}
> +
> +static ssize_t pcie_gadget_store_send_msi(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> + ulong vector;
> + u32 ven_msi;
> +
> + if (strict_strtoul(buf, 0, &vector))
> + return -EINVAL;
> +
> + if (!config->configured_msi)
> + return -EINVAL;
> +
> + if (vector >= config->configured_msi)
> + return -EINVAL;
> +
> + ven_msi = readl(&app_reg->ven_msi_1);
> + ven_msi &= ~VEN_MSI_FUN_NUM_MASK;
> + ven_msi |= 0 << VEN_MSI_FUN_NUM_ID;
> + ven_msi &= ~VEN_MSI_TC_MASK;
> + ven_msi |= 0 << VEN_MSI_TC_ID;
> + ven_msi &= ~VEN_MSI_VECTOR_MASK;
> + ven_msi |= vector << VEN_MSI_VECTOR_ID;
> +
> + /* generating interrupt for msi vector */
> + ven_msi |= VEN_MSI_REQ_EN;
> + writel(ven_msi, &app_reg->ven_msi_1);
> + udelay(1);
> + ven_msi &= ~VEN_MSI_REQ_EN;
> + writel(ven_msi, &app_reg->ven_msi_1);
> +
> + return count;
> +}
> +
> +static ssize_t pcie_gadget_show_vendor_id(
> + struct spear_pcie_gadget_config *config,
> + char *buf)
> +{
> + u32 id;
> +
> + spear_dbi_read_reg(config, PCI_VENDOR_ID, 2, &id);
> +
> + return sprintf(buf, "%x", id);
> +}
> +
> +static ssize_t pcie_gadget_store_vendor_id(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + ulong id;
> +
> + if (strict_strtoul(buf, 0, &id))
> + return -EINVAL;
> +
> + spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id);
> +
> + return count;
> +}
> +
> +static ssize_t pcie_gadget_show_device_id(
> + struct spear_pcie_gadget_config *config,
> + char *buf)
> +{
> + u32 id;
> +
> + spear_dbi_read_reg(config, PCI_DEVICE_ID, 2, &id);
> +
> + return sprintf(buf, "%x", id);
> +}
> +
> +static ssize_t pcie_gadget_store_device_id(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + ulong id;
> +
> + if (strict_strtoul(buf, 0, &id))
> + return -EINVAL;
> +
> + spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id);
> +
> + return count;
> +}
> +
> +static ssize_t pcie_gadget_show_bar0_size(
> + struct spear_pcie_gadget_config *config,
> + char *buf)
> +{
> + return sprintf(buf, "%lx", config->bar0_size);
> +}
> +
> +static ssize_t pcie_gadget_store_bar0_size(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + ulong size;
> + u32 pos, pos1;
> + u32 no_of_bit = 0;
> +
> + if (strict_strtoul(buf, 0, &size))
> + return -EINVAL;
> + /* min bar size is 256 */
> + if (size <= 0x100)
> + size = 0x100;
> + /* max bar size is 1MB*/
> + else if (size >= 0x100000)
> + size = 0x100000;
> + else {
> + pos = 0;
> + pos1 = 0;
> + while (pos < 21) {
> + pos = find_next_bit((ulong *)&size, 21, pos);
> + if (pos != 21)
> + pos1 = pos + 1;
> + pos++;
> + no_of_bit++;
> + }
> + if (no_of_bit == 2)
> + pos1--;
> +
> + size = 1 << pos1;
> + }
> + config->bar0_size = size;
> + spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, size - 1);
> +
> + return count;
> +}
> +
> +static ssize_t pcie_gadget_show_bar0_address(
> + struct spear_pcie_gadget_config *config,
> + char *buf)
> +{
> + struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +
> + u32 address = readl(&app_reg->pim0_mem_addr_start);
> +
> + return sprintf(buf, "%x", address);
> +}
> +
> +static ssize_t pcie_gadget_store_bar0_address(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> + ulong address;
> +
> + if (strict_strtoul(buf, 0, &address))
> + return -EINVAL;
> +
> + address &= ~(config->bar0_size - 1);
> + if (config->va_bar0_address)
> + iounmap(config->va_bar0_address);
> + config->va_bar0_address = ioremap(address, config->bar0_size);
> + if (!config->va_bar0_address)
> + return -ENOMEM;
> +
> + writel(address, &app_reg->pim0_mem_addr_start);
> +
> + return count;
> +}
> +
> +static ssize_t pcie_gadget_show_bar0_rw_offset(
> + struct spear_pcie_gadget_config *config,
> + char *buf)
> +{
> + return sprintf(buf, "%lx", config->bar0_rw_offset);
> +}
> +
> +static ssize_t pcie_gadget_store_bar0_rw_offset(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + ulong offset;
> +
> + if (strict_strtoul(buf, 0, &offset))
> + return -EINVAL;
> +
> + if (offset % 4)
> + return -EINVAL;
> +
> + config->bar0_rw_offset = offset;
> +
> + return count;
> +}
> +
> +static ssize_t pcie_gadget_show_bar0_data(
> + struct spear_pcie_gadget_config *config,
> + char *buf)
> +{
> + ulong data;
> +
> + if (!config->va_bar0_address)
> + return -ENOMEM;
> +
> + data = readl((ulong)config->va_bar0_address + config->bar0_rw_offset);
> +
> + return sprintf(buf, "%lx", data);
> +}
> +
> +static ssize_t pcie_gadget_store_bar0_data(
> + struct spear_pcie_gadget_config *config,
> + const char *buf, size_t count)
> +{
> + ulong data;
> +
> + if (strict_strtoul(buf, 0, &data))
> + return -EINVAL;
> +
> + if (!config->va_bar0_address)
> + return -ENOMEM;
> +
> + writel(data, (ulong)config->va_bar0_address + config->bar0_rw_offset);
> +
> + return count;
> +}
> +
> +/*
> + * Attribute definitions.
> + */
> +
> +#define PCIE_GADGET_TARGET_ATTR_RO(_name) \
> +static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \
> + __CONFIGFS_ATTR(_name, S_IRUGO, pcie_gadget_show_##_name, NULL)
> +
> +#define PCIE_GADGET_TARGET_ATTR_WO(_name) \
> +static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \
> + __CONFIGFS_ATTR(_name, S_IWUSR, NULL, pcie_gadget_store_##_name)
> +
> +#define PCIE_GADGET_TARGET_ATTR_RW(_name) \
> +static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \
> + __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, pcie_gadget_show_##_name, \
> + pcie_gadget_store_##_name)
> +PCIE_GADGET_TARGET_ATTR_RW(link);
> +PCIE_GADGET_TARGET_ATTR_RW(int_type);
> +PCIE_GADGET_TARGET_ATTR_RW(no_of_msi);
> +PCIE_GADGET_TARGET_ATTR_WO(inta);
> +PCIE_GADGET_TARGET_ATTR_WO(send_msi);
> +PCIE_GADGET_TARGET_ATTR_RW(vendor_id);
> +PCIE_GADGET_TARGET_ATTR_RW(device_id);
> +PCIE_GADGET_TARGET_ATTR_RW(bar0_size);
> +PCIE_GADGET_TARGET_ATTR_RW(bar0_address);
> +PCIE_GADGET_TARGET_ATTR_RW(bar0_rw_offset);
> +PCIE_GADGET_TARGET_ATTR_RW(bar0_data);
> +
> +static struct configfs_attribute *pcie_gadget_target_attrs[] = {
> + &pcie_gadget_target_link.attr,
> + &pcie_gadget_target_int_type.attr,
> + &pcie_gadget_target_no_of_msi.attr,
> + &pcie_gadget_target_inta.attr,
> + &pcie_gadget_target_send_msi.attr,
> + &pcie_gadget_target_vendor_id.attr,
> + &pcie_gadget_target_device_id.attr,
> + &pcie_gadget_target_bar0_size.attr,
> + &pcie_gadget_target_bar0_address.attr,
> + &pcie_gadget_target_bar0_rw_offset.attr,
> + &pcie_gadget_target_bar0_data.attr,
> + NULL,
> +};
> +
> +static struct pcie_gadget_target *to_target(struct config_item *item)
> +{
> + return item ?
> + container_of(to_configfs_subsystem(to_config_group(item)),
> + struct pcie_gadget_target, subsys) : NULL;
> +}
> +
> +/*
> + * Item operations and type for pcie_gadget_target.
> + */
> +
> +static ssize_t pcie_gadget_target_attr_show(struct config_item *item,
> + struct configfs_attribute *attr,
> + char *buf)
> +{
> + ssize_t ret = -EINVAL;
> + struct pcie_gadget_target *target = to_target(item);
> + struct pcie_gadget_target_attr *t_attr =
> + container_of(attr, struct pcie_gadget_target_attr, attr);
> +
> + if (t_attr->show)
> + ret = t_attr->show(&target->config, buf);
> + return ret;
> +}
> +
> +static ssize_t pcie_gadget_target_attr_store(struct config_item *item,
> + struct configfs_attribute *attr,
> + const char *buf,
> + size_t count)
> +{
> + ssize_t ret = -EINVAL;
> + struct pcie_gadget_target *target = to_target(item);
> + struct pcie_gadget_target_attr *t_attr =
> + container_of(attr, struct pcie_gadget_target_attr, attr);
> +
> + if (t_attr->store)
> + ret = t_attr->store(&target->config, buf, count);
> + return ret;
> +}
> +
> +static struct configfs_item_operations pcie_gadget_target_item_ops = {
> + .show_attribute = pcie_gadget_target_attr_show,
> + .store_attribute = pcie_gadget_target_attr_store,
> +};
> +
> +static struct config_item_type pcie_gadget_target_type = {
> + .ct_attrs = pcie_gadget_target_attrs,
> + .ct_item_ops = &pcie_gadget_target_item_ops,
> + .ct_owner = THIS_MODULE,
> +};
> +
> +static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config)
> +{
> + struct pcie_app_reg __iomem *app_reg = config->va_app_base;
> +
> + /*setup registers for outbound translation */
> +
> + writel(config->base, &app_reg->in0_mem_addr_start);
> + writel(app_reg->in0_mem_addr_start + IN0_MEM_SIZE,
> + &app_reg->in0_mem_addr_limit);
> + writel(app_reg->in0_mem_addr_limit + 1, &app_reg->in1_mem_addr_start);
> + writel(app_reg->in1_mem_addr_start + IN1_MEM_SIZE,
> + &app_reg->in1_mem_addr_limit);
> + writel(app_reg->in1_mem_addr_limit + 1, &app_reg->in_io_addr_start);
> + writel(app_reg->in_io_addr_start + IN_IO_SIZE,
> + &app_reg->in_io_addr_limit);
> + writel(app_reg->in_io_addr_limit + 1, &app_reg->in_cfg0_addr_start);
> + writel(app_reg->in_cfg0_addr_start + IN_CFG0_SIZE,
> + &app_reg->in_cfg0_addr_limit);
> + writel(app_reg->in_cfg0_addr_limit + 1, &app_reg->in_cfg1_addr_start);
> + writel(app_reg->in_cfg1_addr_start + IN_CFG1_SIZE,
> + &app_reg->in_cfg1_addr_limit);
> + writel(app_reg->in_cfg1_addr_limit + 1, &app_reg->in_msg_addr_start);
> + writel(app_reg->in_msg_addr_start + IN_MSG_SIZE,
> + &app_reg->in_msg_addr_limit);
> +
> + writel(app_reg->in0_mem_addr_start, &app_reg->pom0_mem_addr_start);
> + writel(app_reg->in1_mem_addr_start, &app_reg->pom1_mem_addr_start);
> + writel(app_reg->in_io_addr_start, &app_reg->pom_io_addr_start);
> +
> + /*setup registers for inbound translation */
> +
> + /* Keep AORAM mapped at BAR0 as default */
> + config->bar0_size = INBOUND_ADDR_MASK + 1;
> + spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, INBOUND_ADDR_MASK);
> + spear_dbi_write_reg(config, PCI_BASE_ADDRESS_0, 4, 0xC);
> + config->va_bar0_address = ioremap(SPEAR13XX_SYSRAM1_BASE,
> + config->bar0_size);
> +
> + writel(SPEAR13XX_SYSRAM1_BASE, &app_reg->pim0_mem_addr_start);
> + writel(0, &app_reg->pim1_mem_addr_start);
> + writel(INBOUND_ADDR_MASK + 1, &app_reg->mem0_addr_offset_limit);
> +
> + writel(0x0, &app_reg->pim_io_addr_start);
> + writel(0x0, &app_reg->pim_io_addr_start);
> + writel(0x0, &app_reg->pim_rom_addr_start);
> +
> + writel(DEVICE_TYPE_EP | (1 << MISCTRL_EN_ID)
> + | ((u32)1 << REG_TRANSLATION_ENABLE),
> + &app_reg->app_ctrl_0);
> + /* disable all rx interrupts */
> + writel(0, &app_reg->int_mask);
> +
> + /* Select INTA as default*/
> + spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
> +}
> +
> +static int __devinit spear_pcie_gadget_probe(struct platform_device *pdev)
> +{
> + struct resource *res0, *res1;
> + unsigned int status = 0;
> + int irq;
> + struct clk *clk;
> + static struct pcie_gadget_target *target;
> + struct spear_pcie_gadget_config *config;
> + struct config_item *cg_item;
> + struct configfs_subsystem *subsys;
> +
> + /* get resource for application registers*/
> +
> + res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!res0) {
> + dev_err(&pdev->dev, "no resource defined\n");
> + return -EBUSY;
> + }
> + if (!request_mem_region(res0->start, resource_size(res0),
> + pdev->name)) {
> + dev_err(&pdev->dev, "pcie gadget region already claimed\n");
> + return -EBUSY;
> + }
> + /* get resource for dbi registers*/
> +
> + res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> + if (!res1) {
> + dev_err(&pdev->dev, "no resource defined\n");
> + goto err_rel_res0;
> + }
> + if (!request_mem_region(res1->start, resource_size(res1),
> + pdev->name)) {
> + dev_err(&pdev->dev, "pcie gadget region already claimed\n");
> + goto err_rel_res0;
> + }
> +
> + target = kzalloc(sizeof(*target), GFP_KERNEL);
> + if (!target) {
> + dev_err(&pdev->dev, "out of memory\n");
> + status = -ENOMEM;
> + goto err_rel_res;
> + }
> +
> + cg_item = &target->subsys.su_group.cg_item;
> + sprintf(cg_item->ci_namebuf, "pcie_gadget.%d", pdev->id);
> + cg_item->ci_type = &pcie_gadget_target_type;
> + config = &target->config;
> + config->va_app_base = (void __iomem *)ioremap(res0->start,
> + resource_size(res0));
> + if (!config->va_app_base) {
> + dev_err(&pdev->dev, "ioremap fail\n");
> + status = -ENOMEM;
> + goto err_kzalloc;
> + }
> +
> + config->base = (void __iomem *)res1->start;
> +
> + config->va_dbi_base = (void __iomem *)ioremap(res1->start,
> + resource_size(res1));
> + if (!config->va_dbi_base) {
> + dev_err(&pdev->dev, "ioremap fail\n");
> + status = -ENOMEM;
> + goto err_iounmap_app;
> + }
> +
> + dev_set_drvdata(&pdev->dev, target);
> +
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0) {
> + dev_err(&pdev->dev, "no update irq?\n");
> + status = irq;
> + goto err_iounmap;
> + }
> +
> + status = request_irq(irq, spear_pcie_gadget_irq, 0, pdev->name, NULL);
> + if (status) {
> + dev_err(&pdev->dev, "pcie gadget interrupt IRQ%d already \
> + claimed\n", irq);
> + goto err_iounmap;
> + }
> +
> + /* Register configfs hooks */
> + subsys = &target->subsys;
> + config_group_init(&subsys->su_group);
> + mutex_init(&subsys->su_mutex);
> + status = configfs_register_subsystem(subsys);
> + if (status)
> + goto err_irq;
> +
> + /*
> + * init basic pcie application registers
> + * do not enable clock if it is PCIE0.Ideally , all controller should
> + * have been independent from others with respect to clock. But PCIE1
> + * and 2 depends on PCIE0.So PCIE0 clk is provided during board init.
> + */
> + if (pdev->id == 1) {
> + /*
> + * Ideally CFG Clock should have been also enabled here. But
> + * it is done currently during board init routne
> + */
> + clk = clk_get_sys("pcie1", NULL);
> + if (IS_ERR(clk)) {
> + pr_err("%s:couldn't get clk for pcie1\n", __func__);
> + goto err_irq;
> + }
> + if (clk_enable(clk)) {
> + pr_err("%s:couldn't enable clk for pcie1\n", __func__);
> + goto err_irq;
> + }
> + } else if (pdev->id == 2) {
> + /*
> + * Ideally CFG Clock should have been also enabled here. But
> + * it is done currently during board init routne
> + */
> + clk = clk_get_sys("pcie2", NULL);
> + if (IS_ERR(clk)) {
> + pr_err("%s:couldn't get clk for pcie2\n", __func__);
> + goto err_irq;
> + }
> + if (clk_enable(clk)) {
> + pr_err("%s:couldn't enable clk for pcie2\n", __func__);
> + goto err_irq;
> + }
> + }
> + spear13xx_pcie_device_init(config);
> +
> + return 0;
> +err_irq:
> + free_irq(irq, NULL);
> +err_iounmap:
> + iounmap(config->va_dbi_base);
> +err_iounmap_app:
> + iounmap(config->va_app_base);
> +err_kzalloc:
> + kfree(config);
> +err_rel_res:
> + release_mem_region(res1->start, resource_size(res1));
> +err_rel_res0:
> + release_mem_region(res0->start, resource_size(res0));
> + return status;
> +}
> +
> +static int __devexit spear_pcie_gadget_remove(struct platform_device *pdev)
> +{
> + struct resource *res0, *res1;
> + static struct pcie_gadget_target *target;
> + struct spear_pcie_gadget_config *config;
> + int irq;
> +
> + res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> + irq = platform_get_irq(pdev, 0);
> + target = dev_get_drvdata(&pdev->dev);
> + config = &target->config;
> +
> + free_irq(irq, NULL);
> + iounmap(config->va_dbi_base);
> + iounmap(config->va_app_base);
> + release_mem_region(res1->start, resource_size(res1));
> + release_mem_region(res0->start, resource_size(res0));
> + configfs_unregister_subsystem(&target->subsys);
> + kfree(target);
> +
> + return 0;
> +}
> +
> +static void spear_pcie_gadget_shutdown(struct platform_device *pdev)
> +{
> +}
> +
> +static struct platform_driver spear_pcie_gadget_driver = {
> + .probe = spear_pcie_gadget_probe,
> + .remove = spear_pcie_gadget_remove,
> + .shutdown = spear_pcie_gadget_shutdown,
> + .driver = {
> + .name = "pcie-gadget-spear",
> + .bus = &platform_bus_type
> + },
> +};
> +
> +static int __init spear_pcie_gadget_init(void)
> +{
> + return platform_driver_register(&spear_pcie_gadget_driver);
> +}
> +module_init(spear_pcie_gadget_init);
> +
> +static void __exit spear_pcie_gadget_exit(void)
> +{
> + platform_driver_unregister(&spear_pcie_gadget_driver);
> +}
> +module_exit(spear_pcie_gadget_exit);
> +
> +MODULE_ALIAS("pcie-gadget-spear");
> +MODULE_AUTHOR("Pratyush Anand");
> +MODULE_LICENSE("GPL");
> --
> 1.6.0.2
>
> .
>
^ permalink raw reply
* [PATCHv2] omap: rx51: Add SI4713 FM transmitter
From: Jarkko Nikula @ 2011-02-21 8:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110221095421.6576a98d.jhnikula@gmail.com>
Add SI4713 FM transmitter supplies, platform data and setup to RX-51/N900.
It is connected to line output signals of TLV320AIC34 codec A part.
Driver can be either built-in or a module. It can be tuned with v4l2-ctl
from ivtv-utils. Following examples illustrate the use of it:
v4l2-ctl -d /dev/radio0 --set-ctrl=mute=0 (power up)
v4l2-ctl -d /dev/radio0 -f 107900 (tune 107.9 MHz)
v4l2-ctl -d /dev/radio0 --set-ctrl=mute=1 (power down)
Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>
---
v2: Using pr_err instead of printk. Thanks to
"Varadarajan, Charulatha" <charu@ti.com> for noticing.
---
arch/arm/mach-omap2/board-rx51-peripherals.c | 44 ++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index e75e240..17ef1af 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -36,6 +36,8 @@
#include <sound/tlv320aic3x.h>
#include <sound/tpa6130a2-plat.h>
+#include <media/radio-si4713.h>
+#include <media/si4713.h>
#include <../drivers/staging/iio/light/tsl2563.h>
@@ -47,6 +49,8 @@
#define RX51_WL1251_POWER_GPIO 87
#define RX51_WL1251_IRQ_GPIO 42
+#define RX51_FMTX_RESET_GPIO 163
+#define RX51_FMTX_IRQ 53
/* list all spi devices here */
enum {
@@ -357,10 +361,14 @@ static struct regulator_consumer_supply rx51_vio_supplies[] = {
REGULATOR_SUPPLY("DVDD", "2-0018"),
REGULATOR_SUPPLY("IOVDD", "2-0019"),
REGULATOR_SUPPLY("DVDD", "2-0019"),
+ /* Si4713 IO supply */
+ REGULATOR_SUPPLY("vio", "2-0063"),
};
static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+ /* Si4713 supply */
+ REGULATOR_SUPPLY("vdd", "2-0063"),
};
static struct regulator_consumer_supply rx51_vdac_supply[] = {
@@ -511,6 +519,41 @@ static struct regulator_init_data rx51_vio = {
.consumer_supplies = rx51_vio_supplies,
};
+static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = {
+ .gpio_reset = RX51_FMTX_RESET_GPIO,
+};
+
+static struct i2c_board_info rx51_si4713_board_info __initdata_or_module = {
+ I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH),
+ .platform_data = &rx51_si4713_i2c_data,
+};
+
+static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = {
+ .i2c_bus = 2,
+ .subdev_board_info = &rx51_si4713_board_info,
+};
+
+static struct platform_device rx51_si4713_dev __initdata_or_module = {
+ .name = "radio-si4713",
+ .id = -1,
+ .dev = {
+ .platform_data = &rx51_si4713_data,
+ },
+};
+
+static __init void rx51_init_si4713(void)
+{
+ int err;
+
+ err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
+ if (err) {
+ pr_err("Cannot request si4713 irq gpio. %d\n", err);
+ return;
+ }
+ rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ);
+ platform_device_register(&rx51_si4713_dev);
+}
+
static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
{
/* FIXME this gpio setup is just a placeholder for now */
@@ -921,6 +964,7 @@ void __init rx51_peripherals_init(void)
board_smc91x_init();
rx51_add_gpio_keys();
rx51_init_wl1251();
+ rx51_init_si4713();
spi_register_board_info(rx51_peripherals_spi_board_info,
ARRAY_SIZE(rx51_peripherals_spi_board_info));
--
1.7.2.3
^ permalink raw reply related
* [PATCH v2 2/2] msm: Use explicit GPLv2 licenses
From: Pavel Machek @ 2011-02-21 8:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297728926-15793-2-git-send-email-davidb@codeaurora.org>
On Mon 2011-02-14 16:15:26, David Brown wrote:
> Replace a BSD-style license in Code Aurora Forum authored files with
> an explicit GPLv2.
Thanks!
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* [PATCH 2/4] V4L: mx3_camera: convert to videobuf2
From: Marek Szyprowski @ 2011-02-21 8:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.64.1102180906500.1851@axis700.grange>
Hello,
On Friday, February 18, 2011 9:14 AM Guennadi Liakhovetski wrote:
> Now that soc-camera supports videobuf API v1 and v2, camera-host drivers
> can be converted to videobuf2 individually. This patch converts the
> mx3_camera driver.
>
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
>
> This one is also on git.linuxtv.org already.
>
> drivers/media/video/mx3_camera.c | 342 ++++++++++++++++----------------------
> 1 files changed, 143 insertions(+), 199 deletions(-)
>
> diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
> index b9cb4a4..d61ff0d 100644
> --- a/drivers/media/video/mx3_camera.c
> +++ b/drivers/media/video/mx3_camera.c
> @@ -21,7 +21,7 @@
>
> #include <media/v4l2-common.h>
> #include <media/v4l2-dev.h>
> -#include <media/videobuf-dma-contig.h>
> +#include <media/videobuf2-dma-contig.h>
> #include <media/soc_camera.h>
> #include <media/soc_mediabus.h>
>
> @@ -62,10 +62,16 @@
>
> #define MAX_VIDEO_MEM 16
>
> +enum csi_buffer_state {
> + CSI_BUF_NEEDS_INIT,
> + CSI_BUF_PREPARED,
> +};
> +
> struct mx3_camera_buffer {
> /* common v4l buffer stuff -- must be first */
> - struct videobuf_buffer vb;
> - enum v4l2_mbus_pixelcode code;
> + struct vb2_buffer vb;
> + enum csi_buffer_state state;
> + struct list_head queue;
>
> /* One descriptot per scatterlist (per frame) */
> struct dma_async_tx_descriptor *txd;
> @@ -108,6 +114,9 @@ struct mx3_camera_dev {
> struct list_head capture;
> spinlock_t lock; /* Protects video buffer lists */
> struct mx3_camera_buffer *active;
> + struct vb2_alloc_ctx *alloc_ctx;
> + enum v4l2_field field;
> + int sequence;
>
> /* IDMAC / dmaengine interface */
> struct idmac_channel *idmac_channel[1]; /* We need one channel */
> @@ -130,6 +139,11 @@ static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
> __raw_writel(value, mx3->base + reg);
> }
>
> +static struct mx3_camera_buffer *to_mx3_vb(struct vb2_buffer *vb)
> +{
> + return container_of(vb, struct mx3_camera_buffer, vb);
> +}
> +
> /* Called from the IPU IDMAC ISR */
> static void mx3_cam_dma_done(void *arg)
> {
> @@ -137,20 +151,20 @@ static void mx3_cam_dma_done(void *arg)
> struct dma_chan *chan = desc->txd.chan;
> struct idmac_channel *ichannel = to_idmac_chan(chan);
> struct mx3_camera_dev *mx3_cam = ichannel->client;
> - struct videobuf_buffer *vb;
>
> dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
> desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0);
>
> spin_lock(&mx3_cam->lock);
> if (mx3_cam->active) {
> - vb = &mx3_cam->active->vb;
> -
> - list_del_init(&vb->queue);
> - vb->state = VIDEOBUF_DONE;
> - do_gettimeofday(&vb->ts);
> - vb->field_count++;
> - wake_up(&vb->done);
> + struct vb2_buffer *vb = &mx3_cam->active->vb;
> + struct mx3_camera_buffer *buf = to_mx3_vb(vb);
> +
> + list_del_init(&buf->queue);
> + do_gettimeofday(&vb->v4l2_buf.timestamp);
> + vb->v4l2_buf.field = mx3_cam->field;
> + vb->v4l2_buf.sequence = mx3_cam->sequence++;
> + vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
> }
>
> if (list_empty(&mx3_cam->capture)) {
> @@ -165,38 +179,10 @@ static void mx3_cam_dma_done(void *arg)
> }
>
> mx3_cam->active = list_entry(mx3_cam->capture.next,
> - struct mx3_camera_buffer, vb.queue);
> - mx3_cam->active->vb.state = VIDEOBUF_ACTIVE;
> + struct mx3_camera_buffer, queue);
> spin_unlock(&mx3_cam->lock);
> }
>
> -static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf)
> -{
> - struct soc_camera_device *icd = vq->priv_data;
> - struct videobuf_buffer *vb = &buf->vb;
> - struct dma_async_tx_descriptor *txd = buf->txd;
> - struct idmac_channel *ichan;
> -
> - BUG_ON(in_interrupt());
> -
> - dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
> - vb, vb->baddr, vb->bsize);
> -
> - /*
> - * This waits until this buffer is out of danger, i.e., until it is no
> - * longer in STATE_QUEUED or STATE_ACTIVE
> - */
> - videobuf_waiton(vq, vb, 0, 0);
> - if (txd) {
> - ichan = to_idmac_chan(txd->chan);
> - async_tx_ack(txd);
> - }
> - videobuf_dma_contig_free(vq, vb);
> - buf->txd = NULL;
> -
> - vb->state = VIDEOBUF_NEEDS_INIT;
> -}
> -
> /*
> * Videobuf operations
> */
> @@ -205,10 +191,11 @@ static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf
> * Calculate the __buffer__ (not data) size and number of buffers.
> * Called with .vb_lock held
> */
> -static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
> - unsigned int *size)
> +static int mx3_videobuf_setup(struct vb2_queue *vq,
> + unsigned int *count, unsigned int *num_planes,
> + unsigned long sizes[], void *alloc_ctxs[])
> {
> - struct soc_camera_device *icd = vq->priv_data;
> + struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
> struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
> struct mx3_camera_dev *mx3_cam = ici->priv;
> int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
> @@ -220,104 +207,68 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
> if (!mx3_cam->idmac_channel[0])
> return -EINVAL;
>
> - *size = bytes_per_line * icd->user_height;
> + *num_planes = 1;
> +
> + mx3_cam->sequence = 0;
> + sizes[0] = bytes_per_line * icd->user_height;
> + alloc_ctxs[0] = mx3_cam->alloc_ctx;
>
> if (!*count)
> *count = 32;
>
> - if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
> - *count = MAX_VIDEO_MEM * 1024 * 1024 / *size;
> + if (sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
> + *count = MAX_VIDEO_MEM * 1024 * 1024 / sizes[0];
>
> return 0;
> }
>
> /* Called with .vb_lock held */
vb_lock has no meaning in vb2, so the above line should be removed imho.
> -static int mx3_videobuf_prepare(struct videobuf_queue *vq,
> - struct videobuf_buffer *vb, enum v4l2_field field)
> +static int mx3_videobuf_prepare(struct vb2_buffer *vb)
> {
> - struct soc_camera_device *icd = vq->priv_data;
> + struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
> struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
> struct mx3_camera_dev *mx3_cam = ici->priv;
> - struct mx3_camera_buffer *buf =
> - container_of(vb, struct mx3_camera_buffer, vb);
> + struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
> + struct scatterlist *sg;
> + struct mx3_camera_buffer *buf;
> size_t new_size;
> - int ret;
> int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
> icd->current_fmt->host_fmt);
>
> if (bytes_per_line < 0)
> return bytes_per_line;
>
> - new_size = bytes_per_line * icd->user_height;
> + buf = to_mx3_vb(vb);
> + sg = &buf->sg;
>
> - /*
> - * I think, in buf_prepare you only have to protect global data,
> - * the actual buffer is yours
> - */
> -
> - if (buf->code != icd->current_fmt->code ||
> - vb->width != icd->user_width ||
> - vb->height != icd->user_height ||
> - vb->field != field) {
> - buf->code = icd->current_fmt->code;
> - vb->width = icd->user_width;
> - vb->height = icd->user_height;
> - vb->field = field;
> - if (vb->state != VIDEOBUF_NEEDS_INIT)
> - free_buffer(vq, buf);
> - }
> + new_size = bytes_per_line * icd->user_height;
>
> - if (vb->baddr && vb->bsize < new_size) {
> - /* User provided buffer, but it is too small */
> - ret = -ENOMEM;
> - goto out;
> + if (vb2_plane_size(vb, 0) < new_size) {
> + dev_err(icd->dev.parent, "Buffer too small (%lu < %zu)\n",
> + vb2_plane_size(vb, 0), new_size);
> + return -ENOBUFS;
> }
>
> - if (vb->state == VIDEOBUF_NEEDS_INIT) {
> - struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
> - struct scatterlist *sg = &buf->sg;
> -
> - /*
> - * The total size of video-buffers that will be allocated / mapped.
> - * *size that we calculated in videobuf_setup gets assigned to
> - * vb->bsize, and now we use the same calculation to get vb->size.
> - */
> - vb->size = new_size;
> -
> - /* This actually (allocates and) maps buffers */
> - ret = videobuf_iolock(vq, vb, NULL);
> - if (ret)
> - goto fail;
> -
> - /*
> - * We will have to configure the IDMAC channel. It has two slots
> - * for DMA buffers, we shall enter the first two buffers there,
> - * and then submit new buffers in DMA-ready interrupts
> - */
> - sg_init_table(sg, 1);
> - sg_dma_address(sg) = videobuf_to_dma_contig(vb);
> - sg_dma_len(sg) = vb->size;
> + if (buf->state == CSI_BUF_NEEDS_INIT) {
> + sg_dma_address(sg) = (dma_addr_t)icd->vb2_vidq.mem_ops->cookie(
> + vb->planes[0].mem_priv);
You should use vb2_dma_contig_plane_paddr() function from include/media/videobuf2-dma-contig.h
instead of hacking with cookie directly:
sg_dma_address(sg) = vb2_dma_contig_plane_paddr(vb, 0);
Everything else look fine!
> [snip]
Best regards
--
Marek Szyprowski
Samsung Poland R&D Center
^ permalink raw reply
* [PATCH 3/3] OMAP2+: voltage: reorganize, split code from data
From: Gulati, Shweta @ 2011-02-21 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110221020856.7598.34506.stgit@twilight.localdomain>
Hi,
On Mon, Feb 21, 2011 at 7:38 AM, Paul Walmsley <paul@pwsan.com> wrote:
> This is a first pass at reorganizing mach-omap2/voltage.c:
>
> - Separate almost all of the data from the code of mach-omap2/voltage.c.
> ?The code remains in mach-omap2/voltage.c. ?The data goes into one
> ?of several places, depending on what type of data it is:
>
> ?- Silicon process/validation data: mach-omap2/opp*_data.c
> ?- VC (Voltage Controller) data: mach-omap2/vc*_data.c
> ?- VP (Voltage Processor) data: mach-omap2/vp*_data.c
> ?- Voltage domain data: mach-omap2/voltagedomains*_data.c
>
> ?The ultimate goal is for all this data to be autogenerated, the same
> ?way we autogenerate the rest of our data.
>
> - Separate VC and VP common data from VDD-specific VC and VP data.
>
> - Separate common voltage.c code from SoC-specific code; reuse common code.
>
> - Reorganize structures to avoid unnecessary memory loss due to unpacked
> ?fields.
>
> There is much left to be done. ?VC code and VP code should be separated out
> into vc*.c and vp*.c files. ?Many fields in the existing structures are
> superfluous, and should be removed. ?Some code in voltage.c seems to be
> duplicated; that code should be moved into functions of its own. ?Proper
> voltage domain code should be created, as was done with the powerdomain
> and clockdomains, and powerdomains should reference voltagedomains.
>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> ---
> ?arch/arm/mach-omap2/Makefile ? ? ? ? ? ? ? ? ?| ? 20
> ?arch/arm/mach-omap2/omap_opp_data.h ? ? ? ? ? | ? 12
> ?arch/arm/mach-omap2/opp3xxx_data.c ? ? ? ? ? ?| ? 44 +
> ?arch/arm/mach-omap2/opp4xxx_data.c ? ? ? ? ? ?| ? 30 +
> ?arch/arm/mach-omap2/vc.h ? ? ? ? ? ? ? ? ? ? ?| ? 83 ++
> ?arch/arm/mach-omap2/vc3xxx_data.c ? ? ? ? ? ? | ? 63 ++
> ?arch/arm/mach-omap2/vc44xx_data.c ? ? ? ? ? ? | ? 72 ++
> ?arch/arm/mach-omap2/voltage.c ? ? ? ? ? ? ? ? | 1016 +++++++------------------
> ?arch/arm/mach-omap2/voltage.h ? ? ? ? ? ? ? ? | ? 66 ++
> ?arch/arm/mach-omap2/voltagedomains3xxx_data.c | ?104 +++
> ?arch/arm/mach-omap2/voltagedomains44xx_data.c | ?108 +++
> ?arch/arm/mach-omap2/vp.h ? ? ? ? ? ? ? ? ? ? ?| ?143 ++++
> ?arch/arm/mach-omap2/vp3xxx_data.c ? ? ? ? ? ? | ? 82 ++
> ?arch/arm/mach-omap2/vp44xx_data.c ? ? ? ? ? ? | ? 97 ++
> ?14 files changed, 1192 insertions(+), 748 deletions(-)
> ?create mode 100644 arch/arm/mach-omap2/vc.h
> ?create mode 100644 arch/arm/mach-omap2/vc3xxx_data.c
> ?create mode 100644 arch/arm/mach-omap2/vc44xx_data.c
> ?create mode 100644 arch/arm/mach-omap2/voltagedomains3xxx_data.c
> ?create mode 100644 arch/arm/mach-omap2/voltagedomains44xx_data.c
> ?create mode 100644 arch/arm/mach-omap2/vp.h
> ?create mode 100644 arch/arm/mach-omap2/vp3xxx_data.c
> ?create mode 100644 arch/arm/mach-omap2/vp44xx_data.c
>
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index 1c0c2b0..d5c1dba 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -59,10 +59,10 @@ endif
> ?# Power Management
> ?ifeq ($(CONFIG_PM),y)
> ?obj-$(CONFIG_ARCH_OMAP2) ? ? ? ? ? ? ? += pm24xx.o
> -obj-$(CONFIG_ARCH_OMAP2) ? ? ? ? ? ? ? += sleep24xx.o pm_bus.o voltage.o
> -obj-$(CONFIG_ARCH_OMAP3) ? ? ? ? ? ? ? += pm34xx.o sleep34xx.o voltage.o \
> +obj-$(CONFIG_ARCH_OMAP2) ? ? ? ? ? ? ? += sleep24xx.o pm_bus.o
> +obj-$(CONFIG_ARCH_OMAP3) ? ? ? ? ? ? ? += pm34xx.o sleep34xx.o \
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cpuidle34xx.o pm_bus.o
> -obj-$(CONFIG_ARCH_OMAP4) ? ? ? ? ? ? ? += pm44xx.o voltage.o pm_bus.o
> +obj-$(CONFIG_ARCH_OMAP4) ? ? ? ? ? ? ? += pm44xx.o pm_bus.o
> ?obj-$(CONFIG_PM_DEBUG) ? ? ? ? ? ? ? ? += pm-debug.o
> ?obj-$(CONFIG_OMAP_SMARTREFLEX) ? ? ? ? ?+= sr_device.o smartreflex.o
> ?obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) ?+= smartreflex-class3.o
> @@ -78,13 +78,23 @@ endif
>
> ?# PRCM
> ?obj-$(CONFIG_ARCH_OMAP2) ? ? ? ? ? ? ? += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
> -obj-$(CONFIG_ARCH_OMAP3) ? ? ? ? ? ? ? += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
> +obj-$(CONFIG_ARCH_OMAP3) ? ? ? ? ? ? ? += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?vc3xxx_data.o vp3xxx_data.o
> ?# XXX The presence of cm2xxx_3xxx.o on the line below is temporary and
> ?# will be removed once the OMAP4 part of the codebase is converted to
> ?# use OMAP4-specific PRCM functions.
> ?obj-$(CONFIG_ARCH_OMAP4) ? ? ? ? ? ? ? += prcm.o cm2xxx_3xxx.o cminst44xx.o \
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cm44xx.o prcm_mpu44xx.o \
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?prminst44xx.o
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?prminst44xx.o vc44xx_data.o \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?vp44xx_data.o
> +
> +# OMAP voltage domains
> +voltagedomain-common ? ? ? ? ? ? ? ? ? := voltage.o
> +obj-$(CONFIG_ARCH_OMAP2) ? ? ? ? ? ? ? += $(voltagedomain-common)
> +obj-$(CONFIG_ARCH_OMAP3) ? ? ? ? ? ? ? += $(voltagedomain-common) \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?voltagedomains3xxx_data.o
> +obj-$(CONFIG_ARCH_OMAP4) ? ? ? ? ? ? ? += $(voltagedomain-common) \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?voltagedomains44xx_data.o
>
> ?# OMAP powerdomain framework
> ?powerdomain-common ? ? ? ? ? ? ? ? ? ? += powerdomain.o powerdomain-common.o
> diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h
> index 46ac27d..d8158bb 100644
> --- a/arch/arm/mach-omap2/omap_opp_data.h
> +++ b/arch/arm/mach-omap2/omap_opp_data.h
> @@ -21,6 +21,8 @@
>
> ?#include <plat/omap_hwmod.h>
>
> +#include "voltage.h"
> +
> ?/*
> ?* *BIG FAT WARNING*:
> ?* USE the following ONLY in opp data initialization common to an SoC.
> @@ -69,4 +71,14 @@ struct omap_opp_def {
> ?extern int __init omap_init_opp_table(struct omap_opp_def *opp_def,
> ? ? ? ? ? ? ? ?u32 opp_def_size);
>
> +
> +extern struct omap_volt_data omap34xx_vddmpu_volt_data[];
> +extern struct omap_volt_data omap34xx_vddcore_volt_data[];
> +extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
> +extern struct omap_volt_data omap36xx_vddcore_volt_data[];
> +
> +extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
> +extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
> +extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
> +
> ?#endif ? ? ? ? /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
> diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
> index 0486fce..3c7f0c0 100644
> --- a/arch/arm/mach-omap2/opp3xxx_data.c
> +++ b/arch/arm/mach-omap2/opp3xxx_data.c
> @@ -4,8 +4,9 @@
> ?* Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
> ?* ? ? Nishanth Menon
> ?* ? ? Kevin Hilman
> - * Copyright (C) 2010 Nokia Corporation.
> + * Copyright (C) 2010-2011 Nokia Corporation.
> ?* ? ? ?Eduardo Valentin
> + * ? ? ?Paul Walmsley
> ?*
> ?* This program is free software; you can redistribute it and/or modify
> ?* it under the terms of the GNU General Public License version 2 as
> @@ -20,8 +21,49 @@
>
> ?#include <plat/cpu.h>
>
> +#include "control.h"
> ?#include "omap_opp_data.h"
>
> +/* 34xx */
> +
> +/* VDD1 */
> +struct omap_volt_data omap34xx_vddmpu_volt_data[] = {
> + ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c),
> + ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c),
> + ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18),
> + ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18),
> + ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18),
> + ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +/* VDD2 */
> +struct omap_volt_data omap34xx_vddcore_volt_data[] = {
> + ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c),
> + ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c),
> + ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18),
> + ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +/* 36xx */
> +
> +/* VDD1 */
> +struct omap_volt_data omap36xx_vddmpu_volt_data[] = {
> + ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c),
> + ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16),
> + ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23),
> + ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27),
> + ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +/* VDD2 */
> +struct omap_volt_data omap36xx_vddcore_volt_data[] = {
> + ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c),
> + ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16),
> + ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
The definition of "VOLT_DATA_DEFINE" is there in voltage.h
I think its better to move these Volt_data to voltagedomains files
rather than in
OPP layer files
> +/* OPP data */
> +
> ?static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
> ? ? ? ?/* MPU OPP1 */
> ? ? ? ?OPP_INITIALIZER("mpu", true, 125000000, 975000),
> diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
> index a11fa56..addaf70 100644
> --- a/arch/arm/mach-omap2/opp4xxx_data.c
> +++ b/arch/arm/mach-omap2/opp4xxx_data.c
> @@ -5,8 +5,9 @@
> ?* ? ? Nishanth Menon
> ?* ? ? Kevin Hilman
> ?* ? ? Thara Gopinath
> - * Copyright (C) 2010 Nokia Corporation.
> + * Copyright (C) 2010-2011 Nokia Corporation.
> ?* ? ? ?Eduardo Valentin
> + * ? ? ?Paul Walmsley
> ?*
> ?* This program is free software; you can redistribute it and/or modify
> ?* it under the terms of the GNU General Public License version 2 as
> @@ -21,8 +22,35 @@
>
> ?#include <plat/cpu.h>
>
> +#include "control.h"
> ?#include "omap_opp_data.h"
>
> +/*
> + * Structures containing OMAP4430 voltage supported and various
> + * voltage dependent data for each VDD.
> + */
> +struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
> + ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
> + ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
> + ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
> + ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
> + ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
> + ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
> + ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
> + ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
> + ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
> + ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
> + ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
> + ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
Same.
> ?static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
> ? ? ? ?/* MPU OPP1 - OPP50 */
> ? ? ? ?OPP_INITIALIZER("mpu", true, 300000000, 1100000),
> diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
> new file mode 100644
> index 0000000..e776777
> --- /dev/null
> +++ b/arch/arm/mach-omap2/vc.h
> @@ -0,0 +1,83 @@
> +/*
> + * OMAP3/4 Voltage Controller (VC) structure and macro definitions
> + *
> + * Copyright (C) 2007, 2010 Texas Instruments, Inc.
> + * Rajendra Nayak <rnayak@ti.com>
> + * Lesly A M <x0080970@ti.com>
> + * Thara Gopinath <thara@ti.com>
> + *
> + * Copyright (C) 2008, 2011 Nokia Corporation
> + * Kalle Jokiniemi
> + * Paul Walmsley
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + */
> +#ifndef __ARCH_ARM_MACH_OMAP2_VC_H
> +#define __ARCH_ARM_MACH_OMAP2_VC_H
> +
> +#include <linux/kernel.h>
> +
> +/**
> + * struct omap_vc_common_data - per-VC register/bitfield data
> + * @cmd_on_mask: ON bitmask in PRM_VC_CMD_VAL* register
> + * @valid: VALID bitmask in PRM_VC_BYPASS_VAL register
> + * @smps_sa_reg: Offset of PRM_VC_SMPS_SA reg from PRM start
> + * @smps_volra_reg: Offset of PRM_VC_SMPS_VOL_RA reg from PRM start
> + * @bypass_val_reg: Offset of PRM_VC_BYPASS_VAL reg from PRM start
> + * @data_shift: DATA field shift in PRM_VC_BYPASS_VAL register
> + * @slaveaddr_shift: SLAVEADDR field shift in PRM_VC_BYPASS_VAL register
> + * @regaddr_shift: REGADDR field shift in PRM_VC_BYPASS_VAL register
> + * @cmd_on_shift: ON field shift in PRM_VC_CMD_VAL_* register
> + * @cmd_onlp_shift: ONLP field shift in PRM_VC_CMD_VAL_* register
> + * @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register
> + * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register
> + *
> + * XXX One of cmd_on_mask and cmd_on_shift are not needed
> + * XXX VALID should probably be a shift, not a mask
> + */
> +struct omap_vc_common_data {
> + ? ? ? u32 cmd_on_mask;
> + ? ? ? u32 valid;
> + ? ? ? u8 smps_sa_reg;
> + ? ? ? u8 smps_volra_reg;
> + ? ? ? u8 bypass_val_reg;
> + ? ? ? u8 data_shift;
> + ? ? ? u8 slaveaddr_shift;
> + ? ? ? u8 regaddr_shift;
> + ? ? ? u8 cmd_on_shift;
> + ? ? ? u8 cmd_onlp_shift;
> + ? ? ? u8 cmd_ret_shift;
> + ? ? ? u8 cmd_off_shift;
> +};
> +
> +/**
> + * struct omap_vc_instance_data - VC per-instance data
> + * @vc_common: pointer to VC common data for this platform
> + * @smps_sa_mask: SA* bitmask in the PRM_VC_SMPS_SA register
> + * @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register
> + * @smps_sa_shift: SA* field shift in the PRM_VC_SMPS_SA register
> + * @smps_volra_shift: VOLRA* field shift in the PRM_VC_VOL_RA register
> + *
> + * XXX It is not necessary to have both a *_mask and a *_shift -
> + * ? ? remove one
> + */
> +struct omap_vc_instance_data {
> + ? ? ? const struct omap_vc_common_data *vc_common;
> + ? ? ? u32 smps_sa_mask;
> + ? ? ? u32 smps_volra_mask;
> + ? ? ? u8 cmdval_reg;
> + ? ? ? u8 smps_sa_shift;
> + ? ? ? u8 smps_volra_shift;
> +};
> +
> +extern struct omap_vc_instance_data omap3_vc1_data;
> +extern struct omap_vc_instance_data omap3_vc2_data;
> +
> +extern struct omap_vc_instance_data omap4_vc_mpu_data;
> +extern struct omap_vc_instance_data omap4_vc_iva_data;
> +extern struct omap_vc_instance_data omap4_vc_core_data;
> +
> +#endif
> +
> diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
> new file mode 100644
> index 0000000..f37dc4b
> --- /dev/null
> +++ b/arch/arm/mach-omap2/vc3xxx_data.c
> @@ -0,0 +1,63 @@
> +/*
> + * OMAP3 Voltage Controller (VC) data
> + *
> + * Copyright (C) 2007, 2010 Texas Instruments, Inc.
> + * Rajendra Nayak <rnayak@ti.com>
> + * Lesly A M <x0080970@ti.com>
> + * Thara Gopinath <thara@ti.com>
> + *
> + * Copyright (C) 2008, 2011 Nokia Corporation
> + * Kalle Jokiniemi
> + * Paul Walmsley
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +
> +#include <plat/common.h>
> +
> +#include "prm-regbits-34xx.h"
> +#include "voltage.h"
> +
> +#include "vc.h"
> +
> +/*
> + * VC data common to 34xx/36xx chips
> + * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
> + */
> +static struct omap_vc_common_data omap3_vc_common = {
> + ? ? ? .smps_sa_reg ? ? = OMAP3_PRM_VC_SMPS_SA_OFFSET,
> + ? ? ? .smps_volra_reg ?= OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
> + ? ? ? .bypass_val_reg ?= OMAP3_PRM_VC_BYPASS_VAL_OFFSET,
> + ? ? ? .data_shift ? ? ?= OMAP3430_DATA_SHIFT,
> + ? ? ? .slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT,
> + ? ? ? .regaddr_shift ? = OMAP3430_REGADDR_SHIFT,
> + ? ? ? .valid ? ? ? ? ? = OMAP3430_VALID_MASK,
> + ? ? ? .cmd_on_shift ? ?= OMAP3430_VC_CMD_ON_SHIFT,
> + ? ? ? .cmd_on_mask ? ? = OMAP3430_VC_CMD_ON_MASK,
> + ? ? ? .cmd_onlp_shift ?= OMAP3430_VC_CMD_ONLP_SHIFT,
> + ? ? ? .cmd_ret_shift ? = OMAP3430_VC_CMD_RET_SHIFT,
> + ? ? ? .cmd_off_shift ? = OMAP3430_VC_CMD_OFF_SHIFT,
> +};
> +
> +struct omap_vc_instance_data omap3_vc1_data = {
> + ? ? ? .vc_common = &omap3_vc_common,
> + ? ? ? .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET,
> + ? ? ? .smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT,
> + ? ? ? .smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK,
> + ? ? ? .smps_volra_shift = OMAP3430_VOLRA0_SHIFT,
> + ? ? ? .smps_volra_mask = OMAP3430_VOLRA0_MASK,
> +};
> +
> +struct omap_vc_instance_data omap3_vc2_data = {
> + ? ? ? .vc_common = &omap3_vc_common,
> + ? ? ? .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET,
> + ? ? ? .smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
> + ? ? ? .smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK,
> + ? ? ? .smps_volra_shift = OMAP3430_VOLRA1_SHIFT,
> + ? ? ? .smps_volra_mask = OMAP3430_VOLRA1_MASK,
> +};
> diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
> new file mode 100644
> index 0000000..548cb06
> --- /dev/null
> +++ b/arch/arm/mach-omap2/vc44xx_data.c
> @@ -0,0 +1,72 @@
> +/*
> + * OMAP4 Voltage Controller (VC) data
> + *
> + * Copyright (C) 2007, 2010 Texas Instruments, Inc.
> + * Rajendra Nayak <rnayak@ti.com>
> + * Lesly A M <x0080970@ti.com>
> + * Thara Gopinath <thara@ti.com>
> + *
> + * Copyright (C) 2008, 2011 Nokia Corporation
> + * Kalle Jokiniemi
> + * Paul Walmsley
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +
> +#include <plat/common.h>
> +
> +#include "prm44xx.h"
> +#include "prm-regbits-44xx.h"
> +#include "voltage.h"
> +
> +#include "vc.h"
> +
> +/*
> + * VC data common to 44xx chips
> + * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
> + */
> +static const struct omap_vc_common_data omap4_vc_data = {
> + ? ? ? .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
> + ? ? ? .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
> + ? ? ? .bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET,
> + ? ? ? .data_shift = OMAP4430_DATA_SHIFT,
> + ? ? ? .slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT,
> + ? ? ? .regaddr_shift = OMAP4430_REGADDR_SHIFT,
> + ? ? ? .valid = OMAP4430_VALID_MASK,
> + ? ? ? .cmd_on_shift = OMAP4430_ON_SHIFT,
> + ? ? ? .cmd_on_mask = OMAP4430_ON_MASK,
> + ? ? ? .cmd_onlp_shift = OMAP4430_ONLP_SHIFT,
> + ? ? ? .cmd_ret_shift = OMAP4430_RET_SHIFT,
> + ? ? ? .cmd_off_shift = OMAP4430_OFF_SHIFT,
> +};
> +
> +/* VC instance data for each controllable voltage line */
> +struct omap_vc_instance_data omap4_vc_mpu_data = {
> + ? ? ? .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET,
> + ? ? ? .smps_sa_shift = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT,
> + ? ? ? .smps_sa_mask = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK,
> + ? ? ? .smps_volra_shift = OMAP4430_VOLRA_VDD_MPU_L_SHIFT,
> + ? ? ? .smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
> +};
> +
> +struct omap_vc_instance_data omap4_vc_iva_data = {
> + ? ? ? .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET,
> + ? ? ? .smps_sa_shift = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT,
> + ? ? ? .smps_sa_mask = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK,
> + ? ? ? .smps_volra_shift = OMAP4430_VOLRA_VDD_IVA_L_SHIFT,
> + ? ? ? .smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
> +};
> +
> +struct omap_vc_instance_data omap4_vc_core_data = {
> + ? ? ? .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET,
> + ? ? ? .smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT,
> + ? ? ? .smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK,
> + ? ? ? .smps_volra_shift = OMAP4430_VOLRA_VDD_CORE_L_SHIFT,
> + ? ? ? .smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
> +};
> +
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
> index 3c9bcdc..97f8e73 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c
> @@ -7,8 +7,9 @@
> ?* Rajendra Nayak <rnayak@ti.com>
> ?* Lesly A M <x0080970@ti.com>
> ?*
> - * Copyright (C) 2008 Nokia Corporation
> + * Copyright (C) 2008, 2011 Nokia Corporation
> ?* Kalle Jokiniemi
> + * Paul Walmsley
> ?*
> ?* Copyright (C) 2010 Texas Instruments, Inc.
> ?* Thara Gopinath <thara@ti.com>
> @@ -36,284 +37,28 @@
>
> ?#include "voltage.h"
>
> -#define VP_IDLE_TIMEOUT ? ? ? ? ? ? ? ?200
> -#define VP_TRANXDONE_TIMEOUT ? 300
> +#include "vc.h"
> +#include "vp.h"
> +
> ?#define VOLTAGE_DIR_SIZE ? ? ? 16
>
> -/* Voltage processor register offsets */
> -struct vp_reg_offs {
> - ? ? ? u8 vpconfig;
> - ? ? ? u8 vstepmin;
> - ? ? ? u8 vstepmax;
> - ? ? ? u8 vlimitto;
> - ? ? ? u8 vstatus;
> - ? ? ? u8 voltage;
> -};
This struct is defined in plat/voltage.h not in voltage.c
> -/* Voltage Processor bit field values, shifts and masks */
> -struct vp_reg_val {
> - ? ? ? /* PRM module */
> - ? ? ? u16 prm_mod;
> - ? ? ? /* VPx_VPCONFIG */
> - ? ? ? u32 vpconfig_erroroffset;
> - ? ? ? u16 vpconfig_errorgain;
> - ? ? ? u32 vpconfig_errorgain_mask;
> - ? ? ? u8 vpconfig_errorgain_shift;
> - ? ? ? u32 vpconfig_initvoltage_mask;
> - ? ? ? u8 vpconfig_initvoltage_shift;
> - ? ? ? u32 vpconfig_timeouten;
> - ? ? ? u32 vpconfig_initvdd;
> - ? ? ? u32 vpconfig_forceupdate;
> - ? ? ? u32 vpconfig_vpenable;
> - ? ? ? /* VPx_VSTEPMIN */
> - ? ? ? u8 vstepmin_stepmin;
> - ? ? ? u16 vstepmin_smpswaittimemin;
> - ? ? ? u8 vstepmin_stepmin_shift;
> - ? ? ? u8 vstepmin_smpswaittimemin_shift;
> - ? ? ? /* VPx_VSTEPMAX */
> - ? ? ? u8 vstepmax_stepmax;
> - ? ? ? u16 vstepmax_smpswaittimemax;
> - ? ? ? u8 vstepmax_stepmax_shift;
> - ? ? ? u8 vstepmax_smpswaittimemax_shift;
> - ? ? ? /* VPx_VLIMITTO */
> - ? ? ? u8 vlimitto_vddmin;
> - ? ? ? u8 vlimitto_vddmax;
> - ? ? ? u16 vlimitto_timeout;
> - ? ? ? u8 vlimitto_vddmin_shift;
> - ? ? ? u8 vlimitto_vddmax_shift;
> - ? ? ? u8 vlimitto_timeout_shift;
> - ? ? ? /* PRM_IRQSTATUS*/
> - ? ? ? u32 tranxdone_status;
> -};
Same
> -/* Voltage controller registers and offsets */
> -struct vc_reg_info {
> - ? ? ? /* PRM module */
> - ? ? ? u16 prm_mod;
> - ? ? ? /* VC register offsets */
> - ? ? ? u8 smps_sa_reg;
> - ? ? ? u8 smps_volra_reg;
> - ? ? ? u8 bypass_val_reg;
> - ? ? ? u8 cmdval_reg;
> - ? ? ? u8 voltsetup_reg;
> - ? ? ? /*VC_SMPS_SA*/
> - ? ? ? u8 smps_sa_shift;
> - ? ? ? u32 smps_sa_mask;
> - ? ? ? /* VC_SMPS_VOL_RA */
> - ? ? ? u8 smps_volra_shift;
> - ? ? ? u32 smps_volra_mask;
> - ? ? ? /* VC_BYPASS_VAL */
> - ? ? ? u8 data_shift;
> - ? ? ? u8 slaveaddr_shift;
> - ? ? ? u8 regaddr_shift;
> - ? ? ? u32 valid;
> - ? ? ? /* VC_CMD_VAL */
> - ? ? ? u8 cmd_on_shift;
> - ? ? ? u8 cmd_onlp_shift;
> - ? ? ? u8 cmd_ret_shift;
> - ? ? ? u8 cmd_off_shift;
> - ? ? ? u32 cmd_on_mask;
> - ? ? ? /* PRM_VOLTSETUP */
> - ? ? ? u8 voltsetup_shift;
> - ? ? ? u32 voltsetup_mask;
> -};
Same
> -/**
> - * omap_vdd_info - Per Voltage Domain info
> - *
> - * @volt_data ? ? ? ? ?: voltage table having the distinct voltages supported
> - * ? ? ? ? ? ? ? ? ? ? ? by the domain and other associated per voltage data.
> - * @pmic_info ? ? ? ? ?: pmic specific parameters which should be populted by
> - * ? ? ? ? ? ? ? ? ? ? ? the pmic drivers.
> - * @vp_offs ? ? ? ? ? ?: structure containing the offsets for various
> - * ? ? ? ? ? ? ? ? ? ? ? vp registers
> - * @vp_reg ? ? ? ? ? ? : the register values, shifts, masks for various
> - * ? ? ? ? ? ? ? ? ? ? ? vp registers
> - * @vc_reg ? ? ? ? ? ? : structure containing various various vc registers,
> - * ? ? ? ? ? ? ? ? ? ? ? shifts, masks etc.
> - * @voltdm ? ? ? ? ? ? : pointer to the voltage domain structure
> - * @debug_dir ? ? ? ? ?: debug directory for this voltage domain.
> - * @curr_volt ? ? ? ? ?: current voltage for this vdd.
> - * @ocp_mod ? ? ? ? ? ?: The prm module for accessing the prm irqstatus reg.
> - * @prm_irqst_reg ? ? ?: prm irqstatus register.
> - * @vp_enabled ? ? ? ? : flag to keep track of whether vp is enabled or not
> - * @volt_scale ? ? ? ? : API to scale the voltage of the vdd.
> - */
> -struct omap_vdd_info {
> - ? ? ? struct omap_volt_data *volt_data;
> - ? ? ? struct omap_volt_pmic_info *pmic_info;
> - ? ? ? struct vp_reg_offs vp_offs;
> - ? ? ? struct vp_reg_val vp_reg;
> - ? ? ? struct vc_reg_info vc_reg;
> - ? ? ? struct voltagedomain voltdm;
> - ? ? ? struct dentry *debug_dir;
> - ? ? ? u32 curr_volt;
> - ? ? ? u16 ocp_mod;
> - ? ? ? u8 prm_irqst_reg;
> - ? ? ? bool vp_enabled;
> - ? ? ? u32 (*read_reg) (u16 mod, u8 offset);
> - ? ? ? void (*write_reg) (u32 val, u16 mod, u8 offset);
> - ? ? ? int (*volt_scale) (struct omap_vdd_info *vdd,
> - ? ? ? ? ? ? ? unsigned long target_volt);
> -};
Same
> -static struct omap_vdd_info *vdd_info;
> +static struct omap_vdd_info **vdd_info;
> +
> ?/*
> ?* Number of scalable voltage domains.
> ?*/
> ?static int nr_scalable_vdd;
>
> -/* OMAP3 VDD sturctures */
> -static struct omap_vdd_info omap3_vdd_info[] = {
> - ? ? ? {
> - ? ? ? ? ? ? ? .vp_offs = {
> - ? ? ? ? ? ? ? ? ? ? ? .vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstatus = OMAP3_PRM_VP1_STATUS_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
> - ? ? ? ? ? ? ? },
> - ? ? ? ? ? ? ? .voltdm = {
> - ? ? ? ? ? ? ? ? ? ? ? .name = "mpu",
> - ? ? ? ? ? ? ? },
> - ? ? ? },
> - ? ? ? {
> - ? ? ? ? ? ? ? .vp_offs = {
> - ? ? ? ? ? ? ? ? ? ? ? .vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
> - ? ? ? ? ? ? ? },
> - ? ? ? ? ? ? ? .voltdm = {
> - ? ? ? ? ? ? ? ? ? ? ? .name = "core",
> - ? ? ? ? ? ? ? },
> - ? ? ? },
> -};
> -
> -#define OMAP3_NR_SCALABLE_VDD ARRAY_SIZE(omap3_vdd_info)
> -
> -/* OMAP4 VDD sturctures */
> -static struct omap_vdd_info omap4_vdd_info[] = {
> - ? ? ? {
> - ? ? ? ? ? ? ? .vp_offs = {
> - ? ? ? ? ? ? ? ? ? ? ? .vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
> - ? ? ? ? ? ? ? },
> - ? ? ? ? ? ? ? .voltdm = {
> - ? ? ? ? ? ? ? ? ? ? ? .name = "mpu",
> - ? ? ? ? ? ? ? },
> - ? ? ? },
> - ? ? ? {
> - ? ? ? ? ? ? ? .vp_offs = {
> - ? ? ? ? ? ? ? ? ? ? ? .vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
> - ? ? ? ? ? ? ? },
> - ? ? ? ? ? ? ? .voltdm = {
> - ? ? ? ? ? ? ? ? ? ? ? .name = "iva",
> - ? ? ? ? ? ? ? },
> - ? ? ? },
> - ? ? ? {
> - ? ? ? ? ? ? ? .vp_offs = {
> - ? ? ? ? ? ? ? ? ? ? ? .vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
> - ? ? ? ? ? ? ? ? ? ? ? .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
> - ? ? ? ? ? ? ? },
> - ? ? ? ? ? ? ? .voltdm = {
> - ? ? ? ? ? ? ? ? ? ? ? .name = "core",
> - ? ? ? ? ? ? ? },
> - ? ? ? },
> -};
> -
> -#define OMAP4_NR_SCALABLE_VDD ARRAY_SIZE(omap4_vdd_info)
> -
> -/*
> - * Structures containing OMAP3430/OMAP3630 voltage supported and various
> - * voltage dependent data for each VDD.
> - */
> -#define VOLT_DATA_DEFINE(_v_nom, _efuse_offs, _errminlimit, _errgain) ?\
> -{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> - ? ? ? .volt_nominal ? = _v_nom, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> - ? ? ? .sr_efuse_offs ?= _efuse_offs, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> - ? ? ? .sr_errminlimit = _errminlimit, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> - ? ? ? .vp_errgain ? ? = _errgain ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> -}
> -
> -/* VDD1 */
> -static struct omap_volt_data omap34xx_vddmpu_volt_data[] = {
> - ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c),
> - ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c),
> - ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18),
> - ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18),
> - ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18),
> - ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> -};
> -
> -static struct omap_volt_data omap36xx_vddmpu_volt_data[] = {
> - ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c),
> - ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16),
> - ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23),
> - ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27),
> - ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> -};
> -
> -/* VDD2 */
> -static struct omap_volt_data omap34xx_vddcore_volt_data[] = {
> - ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c),
> - ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c),
> - ? ? ? VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18),
> - ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> -};
> -
> -static struct omap_volt_data omap36xx_vddcore_volt_data[] = {
> - ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c),
> - ? ? ? VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16),
> - ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> -};
> -
> -/*
> - * Structures containing OMAP4430 voltage supported and various
> - * voltage dependent data for each VDD.
> - */
> -static struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
> - ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
> - ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
> - ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
> - ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
> - ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> -};
> -
> -static struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
> - ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
> - ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
> - ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
> - ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> -};
> -
> -static struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
> - ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
> - ? ? ? VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
> - ? ? ? VOLT_DATA_DEFINE(0, 0, 0, 0),
> -};
> +/* XXX document */
> +static s16 prm_mod_offs;
> +static s16 prm_irqst_ocp_mod_offs;
>
> ?static struct dentry *voltage_dir;
>
> ?/* Init function pointers */
> -static void (*vc_init) (struct omap_vdd_info *vdd);
> -static int (*vdd_data_configure) (struct omap_vdd_info *vdd);
> +static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned long target_volt);
>
> ?static u32 omap3_voltage_read_reg(u16 mod, u8 offset)
> ?{
> @@ -336,6 +81,60 @@ static void omap4_voltage_write_reg(u32 val, u16 mod, u8 offset)
> ? ? ? ?omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, mod, offset);
> ?}
>
> +static int __init _config_common_vdd_data(struct omap_vdd_info *vdd)
> +{
> + ? ? ? char *sys_ck_name;
> + ? ? ? struct clk *sys_ck;
> + ? ? ? u32 sys_clk_speed, timeout_val, waittime;
> +
> + ? ? ? /*
> + ? ? ? ?* XXX Clockfw should handle this, or this should be in a
> + ? ? ? ?* struct record
> + ? ? ? ?*/
> + ? ? ? if (cpu_is_omap24xx() || cpu_is_omap34xx())
> + ? ? ? ? ? ? ? sys_ck_name = "sys_ck";
> + ? ? ? else if (cpu_is_omap44xx())
> + ? ? ? ? ? ? ? sys_ck_name = "sys_clkin_ck";
> +
> + ? ? ? /*
> + ? ? ? ?* Sys clk rate is require to calculate vp timeout value and
> + ? ? ? ?* smpswaittimemin and smpswaittimemax.
> + ? ? ? ?*/
> + ? ? ? sys_ck = clk_get(NULL, sys_ck_name);
> + ? ? ? if (IS_ERR(sys_ck)) {
> + ? ? ? ? ? ? ? pr_warning("%s: Could not get the sys clk to calculate"
> + ? ? ? ? ? ? ? ? ? ? ? "various vdd_%s params\n", __func__, vdd->voltdm.name);
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> + ? ? ? sys_clk_speed = clk_get_rate(sys_ck);
> + ? ? ? clk_put(sys_ck);
> + ? ? ? /* Divide to avoid overflow */
> + ? ? ? sys_clk_speed /= 1000;
> +
> + ? ? ? /* Generic voltage parameters */
> + ? ? ? vdd->curr_volt = 1200000;
> + ? ? ? vdd->volt_scale = vp_forceupdate_scale_voltage;
> + ? ? ? vdd->vp_enabled = false;
> +
> + ? ? ? vdd->vp_rt_data.vpconfig_erroroffset =
> + ? ? ? ? ? ? ? (vdd->pmic_info->vp_erroroffset <<
> + ? ? ? ? ? ? ? ?vdd->vp_data->vp_common->vpconfig_erroroffset_shift);
> +
> + ? ? ? timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
> + ? ? ? vdd->vp_rt_data.vlimitto_timeout = timeout_val;
> + ? ? ? vdd->vp_rt_data.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
> + ? ? ? vdd->vp_rt_data.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
> +
> + ? ? ? waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sys_clk_speed) / 1000;
> + ? ? ? vdd->vp_rt_data.vstepmin_smpswaittimemin = waittime;
> + ? ? ? vdd->vp_rt_data.vstepmax_smpswaittimemax = waittime;
> + ? ? ? vdd->vp_rt_data.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
> + ? ? ? vdd->vp_rt_data.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
> +
> + ? ? ? return 0;
> +}
> +
> ?/* Voltage debugfs support */
> ?static int vp_volt_debug_get(void *data, u64 *val)
> ?{
> @@ -347,7 +146,7 @@ static int vp_volt_debug_get(void *data, u64 *val)
> ? ? ? ? ? ? ? ?return -EINVAL;
> ? ? ? ?}
>
> - ? ? ? vsel = vdd->read_reg(vdd->vp_reg.prm_mod, vdd->vp_offs.voltage);
> + ? ? ? vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
> ? ? ? ?pr_notice("curr_vsel = %x\n", vsel);
>
> ? ? ? ?if (!vdd->pmic_info->vsel_to_uv) {
> @@ -380,7 +179,6 @@ DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,
> ?static void vp_latch_vsel(struct omap_vdd_info *vdd)
> ?{
> ? ? ? ?u32 vpconfig;
> - ? ? ? u16 mod;
> ? ? ? ?unsigned long uvdc;
> ? ? ? ?char vsel;
>
> @@ -397,30 +195,27 @@ static void vp_latch_vsel(struct omap_vdd_info *vdd)
> ? ? ? ? ? ? ? ?return;
> ? ? ? ?}
>
> - ? ? ? mod = vdd->vp_reg.prm_mod;
> -
> ? ? ? ?vsel = vdd->pmic_info->uv_to_vsel(uvdc);
>
> - ? ? ? vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
> - ? ? ? vpconfig &= ~(vdd->vp_reg.vpconfig_initvoltage_mask |
> - ? ? ? ? ? ? ? ? ? ? ? vdd->vp_reg.vpconfig_initvdd);
> - ? ? ? vpconfig |= vsel << vdd->vp_reg.vpconfig_initvoltage_shift;
> + ? ? ? vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
> + ? ? ? vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvoltage_mask |
> + ? ? ? ? ? ? ? ? ? ? ? vdd->vp_data->vp_common->vpconfig_initvdd);
> + ? ? ? vpconfig |= vsel << vdd->vp_data->vp_common->vpconfig_initvoltage_shift;
>
> - ? ? ? vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
> + ? ? ? vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
>
> ? ? ? ?/* Trigger initVDD value copy to voltage processor */
> - ? ? ? vdd->write_reg((vpconfig | vdd->vp_reg.vpconfig_initvdd), mod,
> - ? ? ? ? ? ? ? ? ? ? ? vdd->vp_offs.vpconfig);
> + ? ? ? vdd->write_reg((vpconfig | vdd->vp_data->vp_common->vpconfig_initvdd),
> + ? ? ? ? ? ? ? ? ? ? ?prm_mod_offs, vdd->vp_data->vpconfig);
>
> ? ? ? ?/* Clear initVDD copy trigger bit */
> - ? ? ? vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
> + ? ? ? vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
> ?}
>
> ?/* Generic voltage init functions */
> ?static void __init vp_init(struct omap_vdd_info *vdd)
> ?{
> ? ? ? ?u32 vp_val;
> - ? ? ? u16 mod;
>
> ? ? ? ?if (!vdd->read_reg || !vdd->write_reg) {
> ? ? ? ? ? ? ? ?pr_err("%s: No read/write API for accessing vdd_%s regs\n",
> @@ -428,33 +223,31 @@ static void __init vp_init(struct omap_vdd_info *vdd)
> ? ? ? ? ? ? ? ?return;
> ? ? ? ?}
>
> - ? ? ? mod = vdd->vp_reg.prm_mod;
> -
> - ? ? ? vp_val = vdd->vp_reg.vpconfig_erroroffset |
> - ? ? ? ? ? ? ? (vdd->vp_reg.vpconfig_errorgain <<
> - ? ? ? ? ? ? ? vdd->vp_reg.vpconfig_errorgain_shift) |
> - ? ? ? ? ? ? ? vdd->vp_reg.vpconfig_timeouten;
> - ? ? ? vdd->write_reg(vp_val, mod, vdd->vp_offs.vpconfig);
> -
> - ? ? ? vp_val = ((vdd->vp_reg.vstepmin_smpswaittimemin <<
> - ? ? ? ? ? ? ? vdd->vp_reg.vstepmin_smpswaittimemin_shift) |
> - ? ? ? ? ? ? ? (vdd->vp_reg.vstepmin_stepmin <<
> - ? ? ? ? ? ? ? vdd->vp_reg.vstepmin_stepmin_shift));
> - ? ? ? vdd->write_reg(vp_val, mod, vdd->vp_offs.vstepmin);
> -
> - ? ? ? vp_val = ((vdd->vp_reg.vstepmax_smpswaittimemax <<
> - ? ? ? ? ? ? ? vdd->vp_reg.vstepmax_smpswaittimemax_shift) |
> - ? ? ? ? ? ? ? (vdd->vp_reg.vstepmax_stepmax <<
> - ? ? ? ? ? ? ? vdd->vp_reg.vstepmax_stepmax_shift));
> - ? ? ? vdd->write_reg(vp_val, mod, vdd->vp_offs.vstepmax);
> -
> - ? ? ? vp_val = ((vdd->vp_reg.vlimitto_vddmax <<
> - ? ? ? ? ? ? ? vdd->vp_reg.vlimitto_vddmax_shift) |
> - ? ? ? ? ? ? ? (vdd->vp_reg.vlimitto_vddmin <<
> - ? ? ? ? ? ? ? vdd->vp_reg.vlimitto_vddmin_shift) |
> - ? ? ? ? ? ? ? (vdd->vp_reg.vlimitto_timeout <<
> - ? ? ? ? ? ? ? vdd->vp_reg.vlimitto_timeout_shift));
> - ? ? ? vdd->write_reg(vp_val, mod, vdd->vp_offs.vlimitto);
> + ? ? ? vp_val = vdd->vp_rt_data.vpconfig_erroroffset |
> + ? ? ? ? ? ? ? (vdd->vp_rt_data.vpconfig_errorgain <<
> + ? ? ? ? ? ? ? vdd->vp_data->vp_common->vpconfig_errorgain_shift) |
> + ? ? ? ? ? ? ? vdd->vp_data->vp_common->vpconfig_timeouten;
> + ? ? ? vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vpconfig);
> +
> + ? ? ? vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin <<
> + ? ? ? ? ? ? ? vdd->vp_data->vp_common->vstepmin_smpswaittimemin_shift) |
> + ? ? ? ? ? ? ? (vdd->vp_rt_data.vstepmin_stepmin <<
> + ? ? ? ? ? ? ? vdd->vp_data->vp_common->vstepmin_stepmin_shift));
> + ? ? ? vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vstepmin);
> +
> + ? ? ? vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax <<
> + ? ? ? ? ? ? ? vdd->vp_data->vp_common->vstepmax_smpswaittimemax_shift) |
> + ? ? ? ? ? ? ? (vdd->vp_rt_data.vstepmax_stepmax <<
> + ? ? ? ? ? ? ? vdd->vp_data->vp_common->vstepmax_stepmax_shift));
> + ? ? ? vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vstepmax);
> +
> + ? ? ? vp_val = ((vdd->vp_rt_data.vlimitto_vddmax <<
> + ? ? ? ? ? ? ? vdd->vp_data->vp_common->vlimitto_vddmax_shift) |
> + ? ? ? ? ? ? ? (vdd->vp_rt_data.vlimitto_vddmin <<
> + ? ? ? ? ? ? ? vdd->vp_data->vp_common->vlimitto_vddmin_shift) |
> + ? ? ? ? ? ? ? (vdd->vp_rt_data.vlimitto_timeout <<
> + ? ? ? ? ? ? ? vdd->vp_data->vp_common->vlimitto_timeout_shift));
> + ? ? ? vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vlimitto);
> ?}
>
> ?static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)
> @@ -481,23 +274,23 @@ static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)
> ? ? ? ?}
>
> ? ? ? ?(void) debugfs_create_x16("vp_errorgain", S_IRUGO, vdd->debug_dir,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_reg.vpconfig_errorgain));
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_rt_data.vpconfig_errorgain));
> ? ? ? ?(void) debugfs_create_x16("vp_smpswaittimemin", S_IRUGO,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?vdd->debug_dir,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_reg.vstepmin_smpswaittimemin));
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_rt_data.vstepmin_smpswaittimemin));
> ? ? ? ?(void) debugfs_create_x8("vp_stepmin", S_IRUGO, vdd->debug_dir,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_reg.vstepmin_stepmin));
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_rt_data.vstepmin_stepmin));
> ? ? ? ?(void) debugfs_create_x16("vp_smpswaittimemax", S_IRUGO,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?vdd->debug_dir,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_reg.vstepmax_smpswaittimemax));
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_rt_data.vstepmax_smpswaittimemax));
> ? ? ? ?(void) debugfs_create_x8("vp_stepmax", S_IRUGO, vdd->debug_dir,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_reg.vstepmax_stepmax));
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_rt_data.vstepmax_stepmax));
> ? ? ? ?(void) debugfs_create_x8("vp_vddmax", S_IRUGO, vdd->debug_dir,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_reg.vlimitto_vddmax));
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_rt_data.vlimitto_vddmax));
> ? ? ? ?(void) debugfs_create_x8("vp_vddmin", S_IRUGO, vdd->debug_dir,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_reg.vlimitto_vddmin));
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_rt_data.vlimitto_vddmin));
> ? ? ? ?(void) debugfs_create_x16("vp_timeout", S_IRUGO, vdd->debug_dir,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_reg.vlimitto_timeout));
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &(vdd->vp_rt_data.vlimitto_timeout));
> ? ? ? ?(void) debugfs_create_file("curr_vp_volt", S_IRUGO, vdd->debug_dir,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(void *) vdd, &vp_volt_debug_fops);
> ? ? ? ?(void) debugfs_create_file("curr_nominal_volt", S_IRUGO,
> @@ -510,8 +303,12 @@ static int _pre_volt_scale(struct omap_vdd_info *vdd,
> ? ? ? ? ? ? ? ?unsigned long target_volt, u8 *target_vsel, u8 *current_vsel)
> ?{
> ? ? ? ?struct omap_volt_data *volt_data;
> + ? ? ? const struct omap_vc_common_data *vc_common;
> + ? ? ? const struct omap_vp_common_data *vp_common;
> ? ? ? ?u32 vc_cmdval, vp_errgain_val;
> - ? ? ? u16 vp_mod, vc_mod;
> +
> + ? ? ? vc_common = vdd->vc_data->vc_common;
> + ? ? ? vp_common = vdd->vp_data->vp_common;
>
> ? ? ? ?/* Check if suffiecient pmic info is available for this vdd */
> ? ? ? ?if (!vdd->pmic_info) {
> @@ -533,33 +330,30 @@ static int _pre_volt_scale(struct omap_vdd_info *vdd,
> ? ? ? ? ? ? ? ?return -EINVAL;
> ? ? ? ?}
>
> - ? ? ? vp_mod = vdd->vp_reg.prm_mod;
> - ? ? ? vc_mod = vdd->vc_reg.prm_mod;
> -
> ? ? ? ?/* Get volt_data corresponding to target_volt */
> ? ? ? ?volt_data = omap_voltage_get_voltdata(&vdd->voltdm, target_volt);
> ? ? ? ?if (IS_ERR(volt_data))
> ? ? ? ? ? ? ? ?volt_data = NULL;
>
> ? ? ? ?*target_vsel = vdd->pmic_info->uv_to_vsel(target_volt);
> - ? ? ? *current_vsel = vdd->read_reg(vp_mod, vdd->vp_offs.voltage);
> + ? ? ? *current_vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
>
> ? ? ? ?/* Setting the ON voltage to the new target voltage */
> - ? ? ? vc_cmdval = vdd->read_reg(vc_mod, vdd->vc_reg.cmdval_reg);
> - ? ? ? vc_cmdval &= ~vdd->vc_reg.cmd_on_mask;
> - ? ? ? vc_cmdval |= (*target_vsel << vdd->vc_reg.cmd_on_shift);
> - ? ? ? vdd->write_reg(vc_cmdval, vc_mod, vdd->vc_reg.cmdval_reg);
> + ? ? ? vc_cmdval = vdd->read_reg(prm_mod_offs, vdd->vc_data->cmdval_reg);
> + ? ? ? vc_cmdval &= ~vc_common->cmd_on_mask;
> + ? ? ? vc_cmdval |= (*target_vsel << vc_common->cmd_on_shift);
> + ? ? ? vdd->write_reg(vc_cmdval, prm_mod_offs, vdd->vc_data->cmdval_reg);
>
> ? ? ? ?/* Setting vp errorgain based on the voltage */
> ? ? ? ?if (volt_data) {
> - ? ? ? ? ? ? ? vp_errgain_val = vdd->read_reg(vp_mod,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? vdd->vp_offs.vpconfig);
> - ? ? ? ? ? ? ? vdd->vp_reg.vpconfig_errorgain = volt_data->vp_errgain;
> - ? ? ? ? ? ? ? vp_errgain_val &= ~vdd->vp_reg.vpconfig_errorgain_mask;
> - ? ? ? ? ? ? ? vp_errgain_val |= vdd->vp_reg.vpconfig_errorgain <<
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? vdd->vp_reg.vpconfig_errorgain_shift;
> - ? ? ? ? ? ? ? vdd->write_reg(vp_errgain_val, vp_mod,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? vdd->vp_offs.vpconfig);
> + ? ? ? ? ? ? ? vp_errgain_val = vdd->read_reg(prm_mod_offs,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?vdd->vp_data->vpconfig);
> + ? ? ? ? ? ? ? vdd->vp_rt_data.vpconfig_errorgain = volt_data->vp_errgain;
> + ? ? ? ? ? ? ? vp_errgain_val &= ~vp_common->vpconfig_errorgain_mask;
> + ? ? ? ? ? ? ? vp_errgain_val |= vdd->vp_rt_data.vpconfig_errorgain <<
> + ? ? ? ? ? ? ? ? ? ? ? vp_common->vpconfig_errorgain_shift;
> + ? ? ? ? ? ? ? vdd->write_reg(vp_errgain_val, prm_mod_offs,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?vdd->vp_data->vpconfig);
> ? ? ? ?}
>
> ? ? ? ?return 0;
> @@ -585,7 +379,6 @@ static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
> ?{
> ? ? ? ?u32 loop_cnt = 0, retries_cnt = 0;
> ? ? ? ?u32 vc_valid, vc_bypass_val_reg, vc_bypass_value;
> - ? ? ? u16 mod;
> ? ? ? ?u8 target_vsel, current_vsel;
> ? ? ? ?int ret;
>
> @@ -593,20 +386,19 @@ static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
> ? ? ? ?if (ret)
> ? ? ? ? ? ? ? ?return ret;
>
> - ? ? ? mod = vdd->vc_reg.prm_mod;
> -
> - ? ? ? vc_valid = vdd->vc_reg.valid;
> - ? ? ? vc_bypass_val_reg = vdd->vc_reg.bypass_val_reg;
> - ? ? ? vc_bypass_value = (target_vsel << vdd->vc_reg.data_shift) |
> + ? ? ? vc_valid = vdd->vc_data->vc_common->valid;
> + ? ? ? vc_bypass_val_reg = vdd->vc_data->vc_common->bypass_val_reg;
> + ? ? ? vc_bypass_value = (target_vsel << vdd->vc_data->vc_common->data_shift) |
> ? ? ? ? ? ? ? ? ? ? ? ?(vdd->pmic_info->pmic_reg <<
> - ? ? ? ? ? ? ? ? ? ? ? vdd->vc_reg.regaddr_shift) |
> + ? ? ? ? ? ? ? ? ? ? ? vdd->vc_data->vc_common->regaddr_shift) |
> ? ? ? ? ? ? ? ? ? ? ? ?(vdd->pmic_info->i2c_slave_addr <<
> - ? ? ? ? ? ? ? ? ? ? ? vdd->vc_reg.slaveaddr_shift);
> + ? ? ? ? ? ? ? ? ? ? ? vdd->vc_data->vc_common->slaveaddr_shift);
>
> - ? ? ? vdd->write_reg(vc_bypass_value, mod, vc_bypass_val_reg);
> - ? ? ? vdd->write_reg(vc_bypass_value | vc_valid, mod, vc_bypass_val_reg);
> + ? ? ? vdd->write_reg(vc_bypass_value, prm_mod_offs, vc_bypass_val_reg);
> + ? ? ? vdd->write_reg(vc_bypass_value | vc_valid, prm_mod_offs,
> + ? ? ? ? ? ? ? ? ? ? ?vc_bypass_val_reg);
>
> - ? ? ? vc_bypass_value = vdd->read_reg(mod, vc_bypass_val_reg);
> + ? ? ? vc_bypass_value = vdd->read_reg(prm_mod_offs, vc_bypass_val_reg);
> ? ? ? ?/*
> ? ? ? ? * Loop till the bypass command is acknowledged from the SMPS.
> ? ? ? ? * NOTE: This is legacy code. The loop count and retry count needs
> @@ -625,7 +417,8 @@ static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
> ? ? ? ? ? ? ? ? ? ? ? ?loop_cnt = 0;
> ? ? ? ? ? ? ? ? ? ? ? ?udelay(10);
> ? ? ? ? ? ? ? ?}
> - ? ? ? ? ? ? ? vc_bypass_value = vdd->read_reg(mod, vc_bypass_val_reg);
> + ? ? ? ? ? ? ? vc_bypass_value = vdd->read_reg(prm_mod_offs,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? vc_bypass_val_reg);
> ? ? ? ?}
>
> ? ? ? ?_post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
> @@ -637,7 +430,6 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
> ? ? ? ? ? ? ? ?unsigned long target_volt)
> ?{
> ? ? ? ?u32 vpconfig;
> - ? ? ? u16 mod, ocp_mod;
> ? ? ? ?u8 target_vsel, current_vsel, prm_irqst_reg;
> ? ? ? ?int ret, timeout = 0;
>
> @@ -645,20 +437,18 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
> ? ? ? ?if (ret)
> ? ? ? ? ? ? ? ?return ret;
>
> - ? ? ? mod = vdd->vp_reg.prm_mod;
> - ? ? ? ocp_mod = vdd->ocp_mod;
> - ? ? ? prm_irqst_reg = vdd->prm_irqst_reg;
> + ? ? ? prm_irqst_reg = vdd->vp_data->prm_irqst_data->prm_irqst_reg;
>
> ? ? ? ?/*
> ? ? ? ? * Clear all pending TransactionDone interrupt/status. Typical latency
> ? ? ? ? * is <3us
> ? ? ? ? */
> ? ? ? ?while (timeout++ < VP_TRANXDONE_TIMEOUT) {
> - ? ? ? ? ? ? ? vdd->write_reg(vdd->vp_reg.tranxdone_status,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ocp_mod, prm_irqst_reg);
> - ? ? ? ? ? ? ? if (!(vdd->read_reg(ocp_mod, prm_irqst_reg) &
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? vdd->vp_reg.tranxdone_status))
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?prm_irqst_ocp_mod_offs, prm_irqst_reg);
> + ? ? ? ? ? ? ? if (!(vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
> + ? ? ? ? ? ? ? ? ? ? vdd->vp_data->prm_irqst_data->tranxdone_status))
> + ? ? ? ? ? ? ? ? ? ? ? break;
> ? ? ? ? ? ? ? ?udelay(1);
> ? ? ? ?}
> ? ? ? ?if (timeout >= VP_TRANXDONE_TIMEOUT) {
> @@ -668,30 +458,31 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
> ? ? ? ?}
>
> ? ? ? ?/* Configure for VP-Force Update */
> - ? ? ? vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
> - ? ? ? vpconfig &= ~(vdd->vp_reg.vpconfig_initvdd |
> - ? ? ? ? ? ? ? ? ? ? ? vdd->vp_reg.vpconfig_forceupdate |
> - ? ? ? ? ? ? ? ? ? ? ? vdd->vp_reg.vpconfig_initvoltage_mask);
> + ? ? ? vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
> + ? ? ? vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvdd |
> + ? ? ? ? ? ? ? ? ? ? ? vdd->vp_data->vp_common->vpconfig_forceupdate |
> + ? ? ? ? ? ? ? ? ? ? ? vdd->vp_data->vp_common->vpconfig_initvoltage_mask);
> ? ? ? ?vpconfig |= ((target_vsel <<
> - ? ? ? ? ? ? ? ? ? ? ? vdd->vp_reg.vpconfig_initvoltage_shift));
> - ? ? ? vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
> + ? ? ? ? ? ? ? ? ? ? ? vdd->vp_data->vp_common->vpconfig_initvoltage_shift));
> + ? ? ? vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
>
> ? ? ? ?/* Trigger initVDD value copy to voltage processor */
> - ? ? ? vpconfig |= vdd->vp_reg.vpconfig_initvdd;
> - ? ? ? vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
> + ? ? ? vpconfig |= vdd->vp_data->vp_common->vpconfig_initvdd;
> + ? ? ? vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
>
> ? ? ? ?/* Force update of voltage */
> - ? ? ? vpconfig |= vdd->vp_reg.vpconfig_forceupdate;
> - ? ? ? vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
> + ? ? ? vpconfig |= vdd->vp_data->vp_common->vpconfig_forceupdate;
> + ? ? ? vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
>
> ? ? ? ?/*
> ? ? ? ? * Wait for TransactionDone. Typical latency is <200us.
> ? ? ? ? * Depends on SMPSWAITTIMEMIN/MAX and voltage change
> ? ? ? ? */
> ? ? ? ?timeout = 0;
> - ? ? ? omap_test_timeout((vdd->read_reg(ocp_mod, prm_irqst_reg) &
> - ? ? ? ? ? ? ? ? ? ? ? vdd->vp_reg.tranxdone_status),
> - ? ? ? ? ? ? ? ? ? ? ? VP_TRANXDONE_TIMEOUT, timeout);
> + ? ? ? pr_err("prm_irqst_ocp_mod_offs = %08x\n", prm_irqst_ocp_mod_offs);
> + ? ? ? omap_test_timeout((vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
> + ? ? ? ? ? ? ? ? ? ? ? ? ?vdd->vp_data->prm_irqst_data->tranxdone_status),
> + ? ? ? ? ? ? ? ? ? ? ? ? VP_TRANXDONE_TIMEOUT, timeout);
> ? ? ? ?if (timeout >= VP_TRANXDONE_TIMEOUT)
> ? ? ? ? ? ? ? ?pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
> ? ? ? ? ? ? ? ? ? ? ? ?"TRANXDONE never got set after the voltage update\n",
> @@ -705,11 +496,11 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
> ? ? ? ? */
> ? ? ? ?timeout = 0;
> ? ? ? ?while (timeout++ < VP_TRANXDONE_TIMEOUT) {
> - ? ? ? ? ? ? ? vdd->write_reg(vdd->vp_reg.tranxdone_status,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ocp_mod, prm_irqst_reg);
> - ? ? ? ? ? ? ? if (!(vdd->read_reg(ocp_mod, prm_irqst_reg) &
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? vdd->vp_reg.tranxdone_status))
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?prm_irqst_ocp_mod_offs, prm_irqst_reg);
> + ? ? ? ? ? ? ? if (!(vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
> + ? ? ? ? ? ? ? ? ? ? vdd->vp_data->prm_irqst_data->tranxdone_status))
> + ? ? ? ? ? ? ? ? ? ? ? break;
> ? ? ? ? ? ? ? ?udelay(1);
> ? ? ? ?}
>
> @@ -718,222 +509,95 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
> ? ? ? ? ? ? ? ? ? ? ? ?"to clear the TRANXDONE status\n",
> ? ? ? ? ? ? ? ? ? ? ? ?__func__, vdd->voltdm.name);
>
> - ? ? ? vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
> + ? ? ? vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
> ? ? ? ?/* Clear initVDD copy trigger bit */
> - ? ? ? vpconfig &= ~vdd->vp_reg.vpconfig_initvdd;;
> - ? ? ? vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
> + ? ? ? vpconfig &= ~vdd->vp_data->vp_common->vpconfig_initvdd;
> + ? ? ? vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
> ? ? ? ?/* Clear force bit */
> - ? ? ? vpconfig &= ~vdd->vp_reg.vpconfig_forceupdate;
> - ? ? ? vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
> + ? ? ? vpconfig &= ~vdd->vp_data->vp_common->vpconfig_forceupdate;
> + ? ? ? vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
>
> ? ? ? ?return 0;
> ?}
>
> -/* OMAP3 specific voltage init functions */
> +static void __init omap3_vfsm_init(struct omap_vdd_info *vdd)
> +{
> + ? ? ? /*
> + ? ? ? ?* Voltage Manager FSM parameters init
> + ? ? ? ?* XXX This data should be passed in from the board file
> + ? ? ? ?*/
> + ? ? ? vdd->write_reg(OMAP3_CLKSETUP, prm_mod_offs, OMAP3_PRM_CLKSETUP_OFFSET);
> + ? ? ? vdd->write_reg(OMAP3_VOLTOFFSET, prm_mod_offs,
> + ? ? ? ? ? ? ? ? ? ? ?OMAP3_PRM_VOLTOFFSET_OFFSET);
> + ? ? ? vdd->write_reg(OMAP3_VOLTSETUP2, prm_mod_offs,
> + ? ? ? ? ? ? ? ? ? ? ?OMAP3_PRM_VOLTSETUP2_OFFSET);
> +}
>
> -/*
> - * Intializes the voltage controller registers with the PMIC and board
> - * specific parameters and voltage setup times for OMAP3.
> - */
> ?static void __init omap3_vc_init(struct omap_vdd_info *vdd)
> ?{
> - ? ? ? u32 vc_val;
> - ? ? ? u16 mod;
> - ? ? ? u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
> ? ? ? ?static bool is_initialized;
> + ? ? ? u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
> + ? ? ? u32 vc_val;
>
> - ? ? ? if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
> - ? ? ? ? ? ? ? pr_err("%s: PMIC info requried to configure vc for"
> - ? ? ? ? ? ? ? ? ? ? ? "vdd_%s not populated.Hence cannot initialize vc\n",
> - ? ? ? ? ? ? ? ? ? ? ? __func__, vdd->voltdm.name);
> - ? ? ? ? ? ? ? return;
> - ? ? ? }
> -
> - ? ? ? if (!vdd->read_reg || !vdd->write_reg) {
> - ? ? ? ? ? ? ? pr_err("%s: No read/write API for accessing vdd_%s regs\n",
> - ? ? ? ? ? ? ? ? ? ? ? __func__, vdd->voltdm.name);
> + ? ? ? if (is_initialized)
> ? ? ? ? ? ? ? ?return;
> - ? ? ? }
> -
> - ? ? ? mod = vdd->vc_reg.prm_mod;
> -
> - ? ? ? /* Set up the SMPS_SA(i2c slave address in VC */
> - ? ? ? vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_sa_reg);
> - ? ? ? vc_val &= ~vdd->vc_reg.smps_sa_mask;
> - ? ? ? vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_reg.smps_sa_shift;
> - ? ? ? vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_sa_reg);
> -
> - ? ? ? /* Setup the VOLRA(pmic reg addr) in VC */
> - ? ? ? vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_volra_reg);
> - ? ? ? vc_val &= ~vdd->vc_reg.smps_volra_mask;
> - ? ? ? vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_reg.smps_volra_shift;
> - ? ? ? vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_volra_reg);
> -
> - ? ? ? /*Configure the setup times */
> - ? ? ? vc_val = vdd->read_reg(mod, vdd->vc_reg.voltsetup_reg);
> - ? ? ? vc_val &= ~vdd->vc_reg.voltsetup_mask;
> - ? ? ? vc_val |= vdd->pmic_info->volt_setup_time <<
> - ? ? ? ? ? ? ? ? ? ? ? vdd->vc_reg.voltsetup_shift;
> - ? ? ? vdd->write_reg(vc_val, mod, vdd->vc_reg.voltsetup_reg);
>
> ? ? ? ?/* Set up the on, inactive, retention and off voltage */
> ? ? ? ?on_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->on_volt);
> ? ? ? ?onlp_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->onlp_volt);
> ? ? ? ?ret_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->ret_volt);
> ? ? ? ?off_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->off_volt);
> - ? ? ? vc_val ?= ((on_vsel << vdd->vc_reg.cmd_on_shift) |
> - ? ? ? ? ? ? ? (onlp_vsel << vdd->vc_reg.cmd_onlp_shift) |
> - ? ? ? ? ? ? ? (ret_vsel << vdd->vc_reg.cmd_ret_shift) |
> - ? ? ? ? ? ? ? (off_vsel << vdd->vc_reg.cmd_off_shift));
> - ? ? ? vdd->write_reg(vc_val, mod, vdd->vc_reg.cmdval_reg);
> -
> - ? ? ? if (is_initialized)
> - ? ? ? ? ? ? ? return;
> + ? ? ? vc_val ?= ((on_vsel << vdd->vc_data->vc_common->cmd_on_shift) |
> + ? ? ? ? ? ? ? (onlp_vsel << vdd->vc_data->vc_common->cmd_onlp_shift) |
> + ? ? ? ? ? ? ? (ret_vsel << vdd->vc_data->vc_common->cmd_ret_shift) |
> + ? ? ? ? ? ? ? (off_vsel << vdd->vc_data->vc_common->cmd_off_shift));
> + ? ? ? vdd->write_reg(vc_val, prm_mod_offs, vdd->vc_data->cmdval_reg);
>
> - ? ? ? /* Generic VC parameters init */
> - ? ? ? vdd->write_reg(OMAP3430_CMD1_MASK | OMAP3430_RAV1_MASK, mod,
> + ? ? ? /*
> + ? ? ? ?* Generic VC parameters init
> + ? ? ? ?* XXX This data should be abstracted out
> + ? ? ? ?*/
> + ? ? ? vdd->write_reg(OMAP3430_CMD1_MASK | OMAP3430_RAV1_MASK, prm_mod_offs,
> ? ? ? ? ? ? ? ? ? ? ? ?OMAP3_PRM_VC_CH_CONF_OFFSET);
> - ? ? ? vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, mod,
> + ? ? ? vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, prm_mod_offs,
> ? ? ? ? ? ? ? ? ? ? ? ?OMAP3_PRM_VC_I2C_CFG_OFFSET);
> - ? ? ? vdd->write_reg(OMAP3_CLKSETUP, mod, OMAP3_PRM_CLKSETUP_OFFSET);
> - ? ? ? vdd->write_reg(OMAP3_VOLTOFFSET, mod, OMAP3_PRM_VOLTOFFSET_OFFSET);
> - ? ? ? vdd->write_reg(OMAP3_VOLTSETUP2, mod, OMAP3_PRM_VOLTSETUP2_OFFSET);
> +
> + ? ? ? omap3_vfsm_init(vdd);
> +
> ? ? ? ?is_initialized = true;
> ?}
>
> -/* Sets up all the VDD related info for OMAP3 */
> -static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
> +
> +/* OMAP4 specific voltage init functions */
> +static void __init omap4_vc_init(struct omap_vdd_info *vdd)
> ?{
> - ? ? ? struct clk *sys_ck;
> - ? ? ? u32 sys_clk_speed, timeout_val, waittime;
> + ? ? ? static bool is_initialized;
> + ? ? ? u32 vc_val;
>
> - ? ? ? if (!vdd->pmic_info) {
> - ? ? ? ? ? ? ? pr_err("%s: PMIC info requried to configure vdd_%s not"
> - ? ? ? ? ? ? ? ? ? ? ? "populated.Hence cannot initialize vdd_%s\n",
> - ? ? ? ? ? ? ? ? ? ? ? __func__, vdd->voltdm.name, vdd->voltdm.name);
> - ? ? ? ? ? ? ? return -EINVAL;
> - ? ? ? }
> + ? ? ? if (is_initialized)
> + ? ? ? ? ? ? ? return;
>
> - ? ? ? if (!strcmp(vdd->voltdm.name, "mpu")) {
> - ? ? ? ? ? ? ? if (cpu_is_omap3630())
> - ? ? ? ? ? ? ? ? ? ? ? vdd->volt_data = omap36xx_vddmpu_volt_data;
> - ? ? ? ? ? ? ? else
> - ? ? ? ? ? ? ? ? ? ? ? vdd->volt_data = omap34xx_vddmpu_volt_data;
> -
> - ? ? ? ? ? ? ? vdd->vp_reg.tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_volra_shift = OMAP3430_VOLRA0_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_volra_mask = OMAP3430_VOLRA0_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.voltsetup_mask = OMAP3430_SETUP_TIME1_MASK;
> - ? ? ? } else if (!strcmp(vdd->voltdm.name, "core")) {
> - ? ? ? ? ? ? ? if (cpu_is_omap3630())
> - ? ? ? ? ? ? ? ? ? ? ? vdd->volt_data = omap36xx_vddcore_volt_data;
> - ? ? ? ? ? ? ? else
> - ? ? ? ? ? ? ? ? ? ? ? vdd->volt_data = omap34xx_vddcore_volt_data;
> -
> - ? ? ? ? ? ? ? vdd->vp_reg.tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_volra_shift = OMAP3430_VOLRA1_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_volra_mask = OMAP3430_VOLRA1_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.voltsetup_shift = OMAP3430_SETUP_TIME2_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.voltsetup_mask = OMAP3430_SETUP_TIME2_MASK;
> - ? ? ? } else {
> - ? ? ? ? ? ? ? pr_warning("%s: vdd_%s does not exisit in OMAP3\n",
> - ? ? ? ? ? ? ? ? ? ? ? __func__, vdd->voltdm.name);
> - ? ? ? ? ? ? ? return -EINVAL;
> - ? ? ? }
> + ? ? ? /* TODO: Configure setup times and CMD_VAL values*/
>
> ? ? ? ?/*
> - ? ? ? ?* Sys clk rate is require to calculate vp timeout value and
> - ? ? ? ?* smpswaittimemin and smpswaittimemax.
> + ? ? ? ?* Generic VC parameters init
> + ? ? ? ?* XXX This data should be abstracted out
> ? ? ? ? */
> - ? ? ? sys_ck = clk_get(NULL, "sys_ck");
> - ? ? ? if (IS_ERR(sys_ck)) {
> - ? ? ? ? ? ? ? pr_warning("%s: Could not get the sys clk to calculate"
> - ? ? ? ? ? ? ? ? ? ? ? "various vdd_%s params\n", __func__, vdd->voltdm.name);
> - ? ? ? ? ? ? ? return -EINVAL;
> - ? ? ? }
> - ? ? ? sys_clk_speed = clk_get_rate(sys_ck);
> - ? ? ? clk_put(sys_ck);
> - ? ? ? /* Divide to avoid overflow */
> - ? ? ? sys_clk_speed /= 1000;
> -
> - ? ? ? /* Generic voltage parameters */
> - ? ? ? vdd->curr_volt = 1200000;
> - ? ? ? vdd->ocp_mod = OCP_MOD;
> - ? ? ? vdd->prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET;
> - ? ? ? vdd->read_reg = omap3_voltage_read_reg;
> - ? ? ? vdd->write_reg = omap3_voltage_write_reg;
> - ? ? ? vdd->volt_scale = vp_forceupdate_scale_voltage;
> - ? ? ? vdd->vp_enabled = false;
> + ? ? ? vc_val = (OMAP4430_RAV_VDD_MPU_L_MASK | OMAP4430_CMD_VDD_MPU_L_MASK |
> + ? ? ? ? ? ? ? ? OMAP4430_RAV_VDD_IVA_L_MASK | OMAP4430_CMD_VDD_IVA_L_MASK |
> + ? ? ? ? ? ? ? ? OMAP4430_RAV_VDD_CORE_L_MASK | OMAP4430_CMD_VDD_CORE_L_MASK);
> + ? ? ? vdd->write_reg(vc_val, prm_mod_offs, OMAP4_PRM_VC_CFG_CHANNEL_OFFSET);
>
> - ? ? ? /* VC parameters */
> - ? ? ? vdd->vc_reg.prm_mod = OMAP3430_GR_MOD;
> - ? ? ? vdd->vc_reg.smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET;
> - ? ? ? vdd->vc_reg.smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET;
> - ? ? ? vdd->vc_reg.bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET;
> - ? ? ? vdd->vc_reg.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET;
> - ? ? ? vdd->vc_reg.data_shift = OMAP3430_DATA_SHIFT;
> - ? ? ? vdd->vc_reg.slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT;
> - ? ? ? vdd->vc_reg.regaddr_shift = OMAP3430_REGADDR_SHIFT;
> - ? ? ? vdd->vc_reg.valid = OMAP3430_VALID_MASK;
> - ? ? ? vdd->vc_reg.cmd_on_shift = OMAP3430_VC_CMD_ON_SHIFT;
> - ? ? ? vdd->vc_reg.cmd_on_mask = OMAP3430_VC_CMD_ON_MASK;
> - ? ? ? vdd->vc_reg.cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT;
> - ? ? ? vdd->vc_reg.cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT;
> - ? ? ? vdd->vc_reg.cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT;
> -
> - ? ? ? vdd->vp_reg.prm_mod = OMAP3430_GR_MOD;
> -
> - ? ? ? /* VPCONFIG bit fields */
> - ? ? ? vdd->vp_reg.vpconfig_erroroffset = (vdd->pmic_info->vp_erroroffset <<
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?OMAP3430_ERROROFFSET_SHIFT);
> - ? ? ? vdd->vp_reg.vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK;
> - ? ? ? vdd->vp_reg.vpconfig_errorgain_shift = OMAP3430_ERRORGAIN_SHIFT;
> - ? ? ? vdd->vp_reg.vpconfig_initvoltage_shift = OMAP3430_INITVOLTAGE_SHIFT;
> - ? ? ? vdd->vp_reg.vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK;
> - ? ? ? vdd->vp_reg.vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK;
> - ? ? ? vdd->vp_reg.vpconfig_initvdd = OMAP3430_INITVDD_MASK;
> - ? ? ? vdd->vp_reg.vpconfig_forceupdate = OMAP3430_FORCEUPDATE_MASK;
> - ? ? ? vdd->vp_reg.vpconfig_vpenable = OMAP3430_VPENABLE_MASK;
> -
> - ? ? ? /* VSTEPMIN VSTEPMAX bit fields */
> - ? ? ? waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sys_clk_speed) / 1000;
> - ? ? ? vdd->vp_reg.vstepmin_smpswaittimemin = waittime;
> - ? ? ? vdd->vp_reg.vstepmax_smpswaittimemax = waittime;
> - ? ? ? vdd->vp_reg.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
> - ? ? ? vdd->vp_reg.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
> - ? ? ? vdd->vp_reg.vstepmin_smpswaittimemin_shift =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP3430_SMPSWAITTIMEMIN_SHIFT;
> - ? ? ? vdd->vp_reg.vstepmax_smpswaittimemax_shift =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP3430_SMPSWAITTIMEMAX_SHIFT;
> - ? ? ? vdd->vp_reg.vstepmin_stepmin_shift = OMAP3430_VSTEPMIN_SHIFT;
> - ? ? ? vdd->vp_reg.vstepmax_stepmax_shift = OMAP3430_VSTEPMAX_SHIFT;
> -
> - ? ? ? /* VLIMITTO bit fields */
> - ? ? ? timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
> - ? ? ? vdd->vp_reg.vlimitto_timeout = timeout_val;
> - ? ? ? vdd->vp_reg.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
> - ? ? ? vdd->vp_reg.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
> - ? ? ? vdd->vp_reg.vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT;
> - ? ? ? vdd->vp_reg.vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT;
> - ? ? ? vdd->vp_reg.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT;
> + ? ? ? /* XXX These are magic numbers and do not belong! */
> + ? ? ? vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
> + ? ? ? vdd->write_reg(vc_val, prm_mod_offs, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
>
> - ? ? ? return 0;
> + ? ? ? is_initialized = true;
> ?}
>
> -/* OMAP4 specific voltage init functions */
> -static void __init omap4_vc_init(struct omap_vdd_info *vdd)
> +static void __init omap_vc_init(struct omap_vdd_info *vdd)
> ?{
> ? ? ? ?u32 vc_val;
> - ? ? ? u16 mod;
> - ? ? ? static bool is_initialized;
>
> ? ? ? ?if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
> ? ? ? ? ? ? ? ?pr_err("%s: PMIC info requried to configure vc for"
> @@ -948,173 +612,61 @@ static void __init omap4_vc_init(struct omap_vdd_info *vdd)
> ? ? ? ? ? ? ? ?return;
> ? ? ? ?}
>
> - ? ? ? mod = vdd->vc_reg.prm_mod;
> -
> ? ? ? ?/* Set up the SMPS_SA(i2c slave address in VC */
> - ? ? ? vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_sa_reg);
> - ? ? ? vc_val &= ~vdd->vc_reg.smps_sa_mask;
> - ? ? ? vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_reg.smps_sa_shift;
> - ? ? ? vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_sa_reg);
> + ? ? ? vc_val = vdd->read_reg(prm_mod_offs,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?vdd->vc_data->vc_common->smps_sa_reg);
> + ? ? ? vc_val &= ~vdd->vc_data->smps_sa_mask;
> + ? ? ? vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_data->smps_sa_shift;
> + ? ? ? vdd->write_reg(vc_val, prm_mod_offs,
> + ? ? ? ? ? ? ? ? ? ? ?vdd->vc_data->vc_common->smps_sa_reg);
>
> ? ? ? ?/* Setup the VOLRA(pmic reg addr) in VC */
> - ? ? ? vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_volra_reg);
> - ? ? ? vc_val &= ~vdd->vc_reg.smps_volra_mask;
> - ? ? ? vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_reg.smps_volra_shift;
> - ? ? ? vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_volra_reg);
> -
> - ? ? ? /* TODO: Configure setup times and CMD_VAL values*/
> -
> - ? ? ? if (is_initialized)
> - ? ? ? ? ? ? ? return;
> -
> - ? ? ? /* Generic VC parameters init */
> - ? ? ? vc_val = (OMAP4430_RAV_VDD_MPU_L_MASK | OMAP4430_CMD_VDD_MPU_L_MASK |
> - ? ? ? ? ? ? ? OMAP4430_RAV_VDD_IVA_L_MASK | OMAP4430_CMD_VDD_IVA_L_MASK |
> - ? ? ? ? ? ? ? OMAP4430_RAV_VDD_CORE_L_MASK | OMAP4430_CMD_VDD_CORE_L_MASK);
> - ? ? ? vdd->write_reg(vc_val, mod, OMAP4_PRM_VC_CFG_CHANNEL_OFFSET);
> -
> - ? ? ? vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
> - ? ? ? vdd->write_reg(vc_val, mod, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
> + ? ? ? vc_val = vdd->read_reg(prm_mod_offs,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?vdd->vc_data->vc_common->smps_volra_reg);
> + ? ? ? vc_val &= ~vdd->vc_data->smps_volra_mask;
> + ? ? ? vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_data->smps_volra_shift;
> + ? ? ? vdd->write_reg(vc_val, prm_mod_offs,
> + ? ? ? ? ? ? ? ? ? ? ?vdd->vc_data->vc_common->smps_volra_reg);
> +
> + ? ? ? /* Configure the setup times */
> + ? ? ? vc_val = vdd->read_reg(prm_mod_offs, vdd->vfsm->voltsetup_reg);
> + ? ? ? vc_val &= ~vdd->vfsm->voltsetup_mask;
> + ? ? ? vc_val |= vdd->pmic_info->volt_setup_time <<
> + ? ? ? ? ? ? ? ? ? ? ? vdd->vfsm->voltsetup_shift;
> + ? ? ? vdd->write_reg(vc_val, prm_mod_offs, vdd->vfsm->voltsetup_reg);
>
> - ? ? ? is_initialized = true;
> + ? ? ? if (cpu_is_omap34xx())
> + ? ? ? ? ? ? ? omap3_vc_init(vdd);
> + ? ? ? else if (cpu_is_omap44xx())
> + ? ? ? ? ? ? ? omap4_vc_init(vdd);
> ?}
>
> -/* Sets up all the VDD related info for OMAP4 */
> -static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
> +static int __init omap_vdd_data_configure(struct omap_vdd_info *vdd)
> ?{
> - ? ? ? struct clk *sys_ck;
> - ? ? ? u32 sys_clk_speed, timeout_val, waittime;
> + ? ? ? int ret = -EINVAL;
>
> ? ? ? ?if (!vdd->pmic_info) {
> ? ? ? ? ? ? ? ?pr_err("%s: PMIC info requried to configure vdd_%s not"
> ? ? ? ? ? ? ? ? ? ? ? ?"populated.Hence cannot initialize vdd_%s\n",
> ? ? ? ? ? ? ? ? ? ? ? ?__func__, vdd->voltdm.name, vdd->voltdm.name);
> - ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? ? ? ? ? goto ovdc_out;
> ? ? ? ?}
>
> - ? ? ? if (!strcmp(vdd->voltdm.name, "mpu")) {
> - ? ? ? ? ? ? ? vdd->volt_data = omap44xx_vdd_mpu_volt_data;
> - ? ? ? ? ? ? ? vdd->vp_reg.tranxdone_status =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_VP_MPU_TRANXDONE_ST_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_sa_shift =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_sa_mask =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_MPU_L_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.voltsetup_reg =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET;
> - ? ? ? ? ? ? ? vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET;
> - ? ? ? } else if (!strcmp(vdd->voltdm.name, "core")) {
> - ? ? ? ? ? ? ? vdd->volt_data = omap44xx_vdd_core_volt_data;
> - ? ? ? ? ? ? ? vdd->vp_reg.tranxdone_status =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_VP_CORE_TRANXDONE_ST_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.cmdval_reg =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_CORE_L_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.voltsetup_reg =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET;
> - ? ? ? ? ? ? ? vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET;
> - ? ? ? } else if (!strcmp(vdd->voltdm.name, "iva")) {
> - ? ? ? ? ? ? ? vdd->volt_data = omap44xx_vdd_iva_volt_data;
> - ? ? ? ? ? ? ? vdd->vp_reg.tranxdone_status =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_VP_IVA_TRANXDONE_ST_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_sa_shift =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_sa_mask =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_IVA_L_SHIFT;
> - ? ? ? ? ? ? ? vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK;
> - ? ? ? ? ? ? ? vdd->vc_reg.voltsetup_reg =
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET;
> - ? ? ? ? ? ? ? vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET;
> - ? ? ? } else {
> - ? ? ? ? ? ? ? pr_warning("%s: vdd_%s does not exisit in OMAP4\n",
> - ? ? ? ? ? ? ? ? ? ? ? __func__, vdd->voltdm.name);
> - ? ? ? ? ? ? ? return -EINVAL;
> - ? ? ? }
> + ? ? ? if (IS_ERR_VALUE(_config_common_vdd_data(vdd)))
> + ? ? ? ? ? ? ? goto ovdc_out;
>
> - ? ? ? /*
> - ? ? ? ?* Sys clk rate is require to calculate vp timeout value and
> - ? ? ? ?* smpswaittimemin and smpswaittimemax.
> - ? ? ? ?*/
> - ? ? ? sys_ck = clk_get(NULL, "sys_clkin_ck");
> - ? ? ? if (IS_ERR(sys_ck)) {
> - ? ? ? ? ? ? ? pr_warning("%s: Could not get the sys clk to calculate"
> - ? ? ? ? ? ? ? ? ? ? ? "various vdd_%s params\n", __func__, vdd->voltdm.name);
> - ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? if (cpu_is_omap34xx()) {
> + ? ? ? ? ? ? ? vdd->read_reg = omap3_voltage_read_reg;
> + ? ? ? ? ? ? ? vdd->write_reg = omap3_voltage_write_reg;
> + ? ? ? ? ? ? ? ret = 0;
> + ? ? ? } else if (cpu_is_omap44xx()) {
> + ? ? ? ? ? ? ? vdd->read_reg = omap4_voltage_read_reg;
> + ? ? ? ? ? ? ? vdd->write_reg = omap4_voltage_write_reg;
> + ? ? ? ? ? ? ? ret = 0;
> ? ? ? ?}
> - ? ? ? sys_clk_speed = clk_get_rate(sys_ck);
> - ? ? ? clk_put(sys_ck);
> - ? ? ? /* Divide to avoid overflow */
> - ? ? ? sys_clk_speed /= 1000;
> -
> - ? ? ? /* Generic voltage parameters */
> - ? ? ? vdd->curr_volt = 1200000;
> - ? ? ? vdd->ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
> - ? ? ? vdd->read_reg = omap4_voltage_read_reg;
> - ? ? ? vdd->write_reg = omap4_voltage_write_reg;
> - ? ? ? vdd->volt_scale = vp_forceupdate_scale_voltage;
> - ? ? ? vdd->vp_enabled = false;
>
> - ? ? ? /* VC parameters */
> - ? ? ? vdd->vc_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
> - ? ? ? vdd->vc_reg.smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET;
> - ? ? ? vdd->vc_reg.smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET;
> - ? ? ? vdd->vc_reg.bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET;
> - ? ? ? vdd->vc_reg.data_shift = OMAP4430_DATA_SHIFT;
> - ? ? ? vdd->vc_reg.slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT;
> - ? ? ? vdd->vc_reg.regaddr_shift = OMAP4430_REGADDR_SHIFT;
> - ? ? ? vdd->vc_reg.valid = OMAP4430_VALID_MASK;
> - ? ? ? vdd->vc_reg.cmd_on_shift = OMAP4430_ON_SHIFT;
> - ? ? ? vdd->vc_reg.cmd_on_mask = OMAP4430_ON_MASK;
> - ? ? ? vdd->vc_reg.cmd_onlp_shift = OMAP4430_ONLP_SHIFT;
> - ? ? ? vdd->vc_reg.cmd_ret_shift = OMAP4430_RET_SHIFT;
> - ? ? ? vdd->vc_reg.cmd_off_shift = OMAP4430_OFF_SHIFT;
> -
> - ? ? ? vdd->vp_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
> -
> - ? ? ? /* VPCONFIG bit fields */
> - ? ? ? vdd->vp_reg.vpconfig_erroroffset = (vdd->pmic_info->vp_erroroffset <<
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?OMAP4430_ERROROFFSET_SHIFT);
> - ? ? ? vdd->vp_reg.vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK;
> - ? ? ? vdd->vp_reg.vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT;
> - ? ? ? vdd->vp_reg.vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT;
> - ? ? ? vdd->vp_reg.vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK;
> - ? ? ? vdd->vp_reg.vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK;
> - ? ? ? vdd->vp_reg.vpconfig_initvdd = OMAP4430_INITVDD_MASK;
> - ? ? ? vdd->vp_reg.vpconfig_forceupdate = OMAP4430_FORCEUPDATE_MASK;
> - ? ? ? vdd->vp_reg.vpconfig_vpenable = OMAP4430_VPENABLE_MASK;
> -
> - ? ? ? /* VSTEPMIN VSTEPMAX bit fields */
> - ? ? ? waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sys_clk_speed) / 1000;
> - ? ? ? vdd->vp_reg.vstepmin_smpswaittimemin = waittime;
> - ? ? ? vdd->vp_reg.vstepmax_smpswaittimemax = waittime;
> - ? ? ? vdd->vp_reg.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
> - ? ? ? vdd->vp_reg.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
> - ? ? ? vdd->vp_reg.vstepmin_smpswaittimemin_shift =
> - ? ? ? ? ? ? ? ? ? ? ? OMAP4430_SMPSWAITTIMEMIN_SHIFT;
> - ? ? ? vdd->vp_reg.vstepmax_smpswaittimemax_shift =
> - ? ? ? ? ? ? ? ? ? ? ? OMAP4430_SMPSWAITTIMEMAX_SHIFT;
> - ? ? ? vdd->vp_reg.vstepmin_stepmin_shift = OMAP4430_VSTEPMIN_SHIFT;
> - ? ? ? vdd->vp_reg.vstepmax_stepmax_shift = OMAP4430_VSTEPMAX_SHIFT;
> -
> - ? ? ? /* VLIMITTO bit fields */
> - ? ? ? timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
> - ? ? ? vdd->vp_reg.vlimitto_timeout = timeout_val;
> - ? ? ? vdd->vp_reg.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
> - ? ? ? vdd->vp_reg.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
> - ? ? ? vdd->vp_reg.vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT;
> - ? ? ? vdd->vp_reg.vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT;
> - ? ? ? vdd->vp_reg.vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT;
> -
> - ? ? ? return 0;
> +ovdc_out:
> + ? ? ? return ret;
> ?}
>
> ?/* Public functions */
> @@ -1162,8 +714,7 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
> ? ? ? ? ? ? ? ?return 0;
> ? ? ? ?}
>
> - ? ? ? curr_vsel = vdd->read_reg(vdd->vp_reg.prm_mod,
> - ? ? ? ? ? ? ? ? ? ? ? vdd->vp_offs.voltage);
> + ? ? ? curr_vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
>
> ? ? ? ?if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) {
> ? ? ? ? ? ? ? ?pr_warning("%s: PMIC function to convert vsel to voltage"
> @@ -1185,7 +736,6 @@ void omap_vp_enable(struct voltagedomain *voltdm)
> ?{
> ? ? ? ?struct omap_vdd_info *vdd;
> ? ? ? ?u32 vpconfig;
> - ? ? ? u16 mod;
>
> ? ? ? ?if (!voltdm || IS_ERR(voltdm)) {
> ? ? ? ? ? ? ? ?pr_warning("%s: VDD specified does not exist!\n", __func__);
> @@ -1199,8 +749,6 @@ void omap_vp_enable(struct voltagedomain *voltdm)
> ? ? ? ? ? ? ? ?return;
> ? ? ? ?}
>
> - ? ? ? mod = vdd->vp_reg.prm_mod;
> -
> ? ? ? ?/* If VP is already enabled, do nothing. Return */
> ? ? ? ?if (vdd->vp_enabled)
> ? ? ? ? ? ? ? ?return;
> @@ -1208,9 +756,9 @@ void omap_vp_enable(struct voltagedomain *voltdm)
> ? ? ? ?vp_latch_vsel(vdd);
>
> ? ? ? ?/* Enable VP */
> - ? ? ? vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
> - ? ? ? vpconfig |= vdd->vp_reg.vpconfig_vpenable;
> - ? ? ? vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
> + ? ? ? vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
> + ? ? ? vpconfig |= vdd->vp_data->vp_common->vpconfig_vpenable;
> + ? ? ? vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
> ? ? ? ?vdd->vp_enabled = true;
> ?}
>
> @@ -1225,7 +773,6 @@ void omap_vp_disable(struct voltagedomain *voltdm)
> ?{
> ? ? ? ?struct omap_vdd_info *vdd;
> ? ? ? ?u32 vpconfig;
> - ? ? ? u16 mod;
> ? ? ? ?int timeout;
>
> ? ? ? ?if (!voltdm || IS_ERR(voltdm)) {
> @@ -1240,8 +787,6 @@ void omap_vp_disable(struct voltagedomain *voltdm)
> ? ? ? ? ? ? ? ?return;
> ? ? ? ?}
>
> - ? ? ? mod = vdd->vp_reg.prm_mod;
> -
> ? ? ? ?/* If VP is already disabled, do nothing. Return */
> ? ? ? ?if (!vdd->vp_enabled) {
> ? ? ? ? ? ? ? ?pr_warning("%s: Trying to disable VP for vdd_%s when"
> @@ -1250,14 +795,14 @@ void omap_vp_disable(struct voltagedomain *voltdm)
> ? ? ? ?}
>
> ? ? ? ?/* Disable VP */
> - ? ? ? vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
> - ? ? ? vpconfig &= ~vdd->vp_reg.vpconfig_vpenable;
> - ? ? ? vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
> + ? ? ? vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
> + ? ? ? vpconfig &= ~vdd->vp_data->vp_common->vpconfig_vpenable;
> + ? ? ? vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
>
> ? ? ? ?/*
> ? ? ? ? * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
> ? ? ? ? */
> - ? ? ? omap_test_timeout((vdd->read_reg(mod, vdd->vp_offs.vstatus)),
> + ? ? ? omap_test_timeout((vdd->read_reg(prm_mod_offs, vdd->vp_data->vstatus)),
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?VP_IDLE_TIMEOUT, timeout);
>
> ? ? ? ?if (timeout >= VP_IDLE_TIMEOUT)
> @@ -1510,8 +1055,8 @@ struct voltagedomain *omap_voltage_domain_lookup(char *name)
> ? ? ? ?}
>
> ? ? ? ?for (i = 0; i < nr_scalable_vdd; i++) {
> - ? ? ? ? ? ? ? if (!(strcmp(name, vdd_info[i].voltdm.name)))
> - ? ? ? ? ? ? ? ? ? ? ? return &vdd_info[i].voltdm;
> + ? ? ? ? ? ? ? if (!(strcmp(name, vdd_info[i]->voltdm.name)))
> + ? ? ? ? ? ? ? ? ? ? ? return &vdd_info[i]->voltdm;
> ? ? ? ?}
>
> ? ? ? ?return ERR_PTR(-EINVAL);
> @@ -1539,35 +1084,24 @@ int __init omap_voltage_late_init(void)
> ? ? ? ? ? ? ? ?pr_err("%s: Unable to create voltage debugfs main dir\n",
> ? ? ? ? ? ? ? ? ? ? ? ?__func__);
> ? ? ? ?for (i = 0; i < nr_scalable_vdd; i++) {
> - ? ? ? ? ? ? ? if (vdd_data_configure(&vdd_info[i]))
> + ? ? ? ? ? ? ? if (omap_vdd_data_configure(vdd_info[i]))
> ? ? ? ? ? ? ? ? ? ? ? ?continue;
> - ? ? ? ? ? ? ? vc_init(&vdd_info[i]);
> - ? ? ? ? ? ? ? vp_init(&vdd_info[i]);
> - ? ? ? ? ? ? ? vdd_debugfs_init(&vdd_info[i]);
> + ? ? ? ? ? ? ? omap_vc_init(vdd_info[i]);
> + ? ? ? ? ? ? ? vp_init(vdd_info[i]);
> + ? ? ? ? ? ? ? vdd_debugfs_init(vdd_info[i]);
> ? ? ? ?}
>
> ? ? ? ?return 0;
> ?}
>
> -/**
> - * omap_voltage_early_init()- Volatage driver early init
> - */
> -static int __init omap_voltage_early_init(void)
> +/* XXX document */
> +int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_ocp_mod,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct omap_vdd_info *omap_vdd_array[],
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?u8 omap_vdd_count)
> ?{
> - ? ? ? if (cpu_is_omap34xx()) {
> - ? ? ? ? ? ? ? vdd_info = omap3_vdd_info;
> - ? ? ? ? ? ? ? nr_scalable_vdd = OMAP3_NR_SCALABLE_VDD;
> - ? ? ? ? ? ? ? vc_init = omap3_vc_init;
> - ? ? ? ? ? ? ? vdd_data_configure = omap3_vdd_data_configure;
> - ? ? ? } else if (cpu_is_omap44xx()) {
> - ? ? ? ? ? ? ? vdd_info = omap4_vdd_info;
> - ? ? ? ? ? ? ? nr_scalable_vdd = OMAP4_NR_SCALABLE_VDD;
> - ? ? ? ? ? ? ? vc_init = omap4_vc_init;
> - ? ? ? ? ? ? ? vdd_data_configure = omap4_vdd_data_configure;
> - ? ? ? } else {
> - ? ? ? ? ? ? ? pr_warning("%s: voltage driver support not added\n", __func__);
> - ? ? ? }
> -
> + ? ? ? prm_mod_offs = prm_mod;
> + ? ? ? prm_irqst_ocp_mod_offs = prm_irqst_ocp_mod;
> + ? ? ? vdd_info = omap_vdd_array;
> + ? ? ? nr_scalable_vdd = omap_vdd_count;
> ? ? ? ?return 0;
> ?}
> -core_initcall(omap_voltage_early_init);
> diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
> index 5bd204e..af0cf65 100644
> --- a/arch/arm/mach-omap2/voltage.h
> +++ b/arch/arm/mach-omap2/voltage.h
> @@ -16,9 +16,21 @@
>
> ?#include <linux/err.h>
>
> +#include "vc.h"
> +#include "vp.h"
> +
> +/* XXX document */
> ?#define VOLTSCALE_VPFORCEUPDATE ? ? ? ? ? ? ? ?1
> ?#define VOLTSCALE_VCBYPASS ? ? ? ? ? ? 2
>
> +#define VOLT_DATA_DEFINE(_v_nom, _efuse_offs, _errminlimit, _errgain) ?\
> +{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? .volt_nominal ? = _v_nom, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? .sr_efuse_offs ?= _efuse_offs, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? .sr_errminlimit = _errminlimit, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? .vp_errgain ? ? = _errgain ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> +}
> +
> ?/*
> ?* OMAP3 GENERIC setup times. Revisit to see if these needs to be
> ?* passed from board or PMIC file
> @@ -59,6 +71,21 @@
> ?#define OMAP4430_VDD_CORE_OPP100_UV ? ? ? ? ? ?1100000
>
> ?/**
> + * struct omap_vfsm_instance_data - per-voltage manager FSM register/bitfield
> + * data
> + * @voltsetup_mask:
> + * @voltsetup_reg:
> + * @voltsetup_shift:
> + *
> + * XXX What about VOLTOFFSET/VOLTCTRL?
> + */
> +struct omap_vfsm_instance_data {
> + ? ? ? u32 voltsetup_mask;
> + ? ? ? u8 voltsetup_reg;
> + ? ? ? u8 voltsetup_shift;
> +};
> +
> +/**
> ?* struct voltagedomain - omap voltage domain global structure.
> ?* @name: ? ? ?Name of the voltage domain which can be used as a unique
> ?* ? ? ? ? ? ? identifier.
> @@ -113,6 +140,42 @@ struct omap_volt_pmic_info {
> ? ? ? ?u8 (*uv_to_vsel) (unsigned long uV);
> ?};
>
> +/**
> + * omap_vdd_info - Per Voltage Domain info
> + *
> + * @volt_data ? ? ? ? ?: voltage table having the distinct voltages supported
> + * ? ? ? ? ? ? ? ? ? ? ? by the domain and other associated per voltage data.
> + * @pmic_info ? ? ? ? ?: pmic specific parameters which should be populted by
> + * ? ? ? ? ? ? ? ? ? ? ? the pmic drivers.
> + * @vp_data ? ? ? ? ? ?: the register values, shifts, masks for various
> + * ? ? ? ? ? ? ? ? ? ? ? vp registers
> + * @vp_rt_data ? ? ? ? ?: VP data derived at runtime, not predefined
> + * @vc_data ? ? ? ? ? ?: structure containing various various vc registers,
> + * ? ? ? ? ? ? ? ? ? ? ? shifts, masks etc.
> + * @vfsm ? ? ? ? ? ? ? ?: voltage manager FSM data
> + * @voltdm ? ? ? ? ? ? : pointer to the voltage domain structure
> + * @debug_dir ? ? ? ? ?: debug directory for this voltage domain.
> + * @curr_volt ? ? ? ? ?: current voltage for this vdd.
> + * @vp_enabled ? ? ? ? : flag to keep track of whether vp is enabled or not
> + * @volt_scale ? ? ? ? : API to scale the voltage of the vdd.
> + */
> +struct omap_vdd_info {
> + ? ? ? struct omap_volt_data *volt_data;
> + ? ? ? struct omap_volt_pmic_info *pmic_info;
> + ? ? ? struct omap_vp_instance_data *vp_data;
> + ? ? ? struct omap_vp_runtime_data vp_rt_data;
> + ? ? ? struct omap_vc_instance_data *vc_data;
> + ? ? ? const struct omap_vfsm_instance_data *vfsm;
> + ? ? ? struct voltagedomain voltdm;
> + ? ? ? struct dentry *debug_dir;
> + ? ? ? u32 curr_volt;
> + ? ? ? bool vp_enabled;
> + ? ? ? u32 (*read_reg) (u16 mod, u8 offset);
> + ? ? ? void (*write_reg) (u32 val, u16 mod, u8 offset);
> + ? ? ? int (*volt_scale) (struct omap_vdd_info *vdd,
> + ? ? ? ? ? ? ? unsigned long target_volt);
> +};
> +
> ?unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
> ?void omap_vp_enable(struct voltagedomain *voltdm);
> ?void omap_vp_disable(struct voltagedomain *voltdm);
> @@ -125,6 +188,9 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
> ? ? ? ? ? ? ? ?unsigned long volt);
> ?unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);
> ?struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
> +int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_mod,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct omap_vdd_info *omap_vdd_array[],
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?u8 omap_vdd_count);
> ?#ifdef CONFIG_PM
> ?int omap_voltage_register_pmic(struct voltagedomain *voltdm,
> ? ? ? ? ? ? ? ?struct omap_volt_pmic_info *pmic_info);
> diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
> new file mode 100644
> index 0000000..cb92209
> --- /dev/null
> +++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
> @@ -0,0 +1,104 @@
> +/*
> + * OMAP3 voltage domain data
> + *
> + * Copyright (C) 2007, 2010 Texas Instruments, Inc.
> + * Rajendra Nayak <rnayak@ti.com>
> + * Lesly A M <x0080970@ti.com>
> + * Thara Gopinath <thara@ti.com>
> + *
> + * Copyright (C) 2008, 2011 Nokia Corporation
> + * Kalle Jokiniemi
> + * Paul Walmsley
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/debugfs.h>
> +#include <linux/slab.h>
> +#include <linux/init.h>
> +
> +#include <plat/common.h>
> +
> +#include "prm-regbits-34xx.h"
> +#include "prm-regbits-44xx.h"
> +#include "prm44xx.h"
> +#include "prcm44xx.h"
> +#include "prminst44xx.h"
> +#include "control.h"
> +#include "voltage.h"
> +#include "omap_opp_data.h"
> +#include "vc.h"
> +#include "vp.h"
> +
> +/*
> + * VDD data
> + */
> +
> +static const struct omap_vfsm_instance_data omap3_vdd1_vfsm_data = {
> + ? ? ? .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
> + ? ? ? .voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT,
> + ? ? ? .voltsetup_mask = OMAP3430_SETUP_TIME1_MASK,
> +};
> +
> +static struct omap_vdd_info omap3_vdd1_info = {
> + ? ? ? .vp_data = &omap3_vp1_data,
> + ? ? ? .vc_data = &omap3_vc1_data,
> + ? ? ? .vfsm = &omap3_vdd1_vfsm_data,
> + ? ? ? .voltdm = {
> + ? ? ? ? ? ? ? .name = "mpu",
> + ? ? ? },
> +};
> +
> +static const struct omap_vfsm_instance_data omap3_vdd2_vfsm_data = {
> + ? ? ? .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
> + ? ? ? .voltsetup_shift = OMAP3430_SETUP_TIME2_SHIFT,
> + ? ? ? .voltsetup_mask = OMAP3430_SETUP_TIME2_MASK,
> +};
> +
> +static struct omap_vdd_info omap3_vdd2_info = {
> + ? ? ? .vp_data = &omap3_vp2_data,
> + ? ? ? .vc_data = &omap3_vc2_data,
> + ? ? ? .vfsm = &omap3_vdd2_vfsm_data,
> + ? ? ? .voltdm = {
> + ? ? ? ? ? ? ? .name = "core",
> + ? ? ? },
> +};
> +
> +/* OMAP3 VDD sturctures */
> +static struct omap_vdd_info *omap3_vdd_info[] = {
> + ? ? ? &omap3_vdd1_info,
> + ? ? ? &omap3_vdd2_info,
> +};
> +
> +/* OMAP3 specific voltage init functions */
> +static int __init omap3xxx_voltage_early_init(void)
> +{
> + ? ? ? s16 prm_mod = OMAP3430_GR_MOD;
> + ? ? ? s16 prm_irqst_ocp_mod = OCP_MOD;
> +
> + ? ? ? if (!cpu_is_omap34xx())
> + ? ? ? ? ? ? ? return 0;
> +
> + ? ? ? /*
> + ? ? ? ?* XXX Will depend on the process, validation, and binning
> + ? ? ? ?* for the currently-running IC
> + ? ? ? ?*/
> + ? ? ? if (cpu_is_omap3630()) {
> + ? ? ? ? ? ? ? omap3_vdd1_info.volt_data = omap36xx_vddmpu_volt_data;
> + ? ? ? ? ? ? ? omap3_vdd2_info.volt_data = omap36xx_vddcore_volt_data;
> + ? ? ? } else {
> + ? ? ? ? ? ? ? omap3_vdd1_info.volt_data = omap34xx_vddmpu_volt_data;
> + ? ? ? ? ? ? ? omap3_vdd2_info.volt_data = omap34xx_vddcore_volt_data;
> + ? ? ? }
> +
> + ? ? ? return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?omap3_vdd_info,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ARRAY_SIZE(omap3_vdd_info));
> +};
> +core_initcall(omap3xxx_voltage_early_init);
> diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
> new file mode 100644
> index 0000000..52bfd8a
> --- /dev/null
> +++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
> @@ -0,0 +1,108 @@
> +/*
> + * OMAP3/OMAP4 Voltage Management Routines
> + *
> + * Author: Thara Gopinath ? ? ?<thara@ti.com>
> + *
> + * Copyright (C) 2007 Texas Instruments, Inc.
> + * Rajendra Nayak <rnayak@ti.com>
> + * Lesly A M <x0080970@ti.com>
> + *
> + * Copyright (C) 2008 Nokia Corporation
> + * Kalle Jokiniemi
> + *
> + * Copyright (C) 2010 Texas Instruments, Inc.
> + * Thara Gopinath <thara@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/debugfs.h>
> +#include <linux/slab.h>
> +
> +#include <plat/common.h>
> +
> +#include "prm-regbits-34xx.h"
> +#include "prm-regbits-44xx.h"
> +#include "prm44xx.h"
> +#include "prcm44xx.h"
> +#include "prminst44xx.h"
> +#include "control.h"
> +#include "voltage.h"
> +#include "omap_opp_data.h"
> +#include "vc.h"
> +#include "vp.h"
> +
> +/* OMAP4 VDD sturctures */
> +static const struct omap_vfsm_instance_data omap4_vdd_mpu_vfsm_data = {
> + ? ? ? .voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
> +};
> +
> +static struct omap_vdd_info omap4_vdd_mpu_info = {
> + ? ? ? .vp_data = &omap4_vp_mpu_data,
> + ? ? ? .vc_data = &omap4_vc_mpu_data,
> + ? ? ? .vfsm = &omap4_vdd_mpu_vfsm_data,
> + ? ? ? .voltdm = {
> + ? ? ? ? ? ? ? .name = "mpu",
> + ? ? ? },
> +};
> +
> +static const struct omap_vfsm_instance_data omap4_vdd_iva_vfsm_data = {
> + ? ? ? .voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET,
> +};
> +
> +static struct omap_vdd_info omap4_vdd_iva_info = {
> + ? ? ? .vp_data = &omap4_vp_iva_data,
> + ? ? ? .vc_data = &omap4_vc_iva_data,
> + ? ? ? .vfsm = &omap4_vdd_iva_vfsm_data,
> + ? ? ? .voltdm = {
> + ? ? ? ? ? ? ? .name = "iva",
> + ? ? ? },
> +};
> +
> +static const struct omap_vfsm_instance_data omap4_vdd_core_vfsm_data = {
> + ? ? ? .voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
> +};
> +
> +static struct omap_vdd_info omap4_vdd_core_info = {
> + ? ? ? .vp_data = &omap4_vp_core_data,
> + ? ? ? .vc_data = &omap4_vc_core_data,
> + ? ? ? .vfsm = &omap4_vdd_core_vfsm_data,
> + ? ? ? .voltdm = {
> + ? ? ? ? ? ? ? .name = "core",
> + ? ? ? },
> +};
> +
> +static struct omap_vdd_info *omap4_vdd_info[] = {
> + ? ? ? &omap4_vdd_mpu_info,
> + ? ? ? &omap4_vdd_iva_info,
> + ? ? ? &omap4_vdd_core_info,
> +};
> +
> +/* OMAP4 specific voltage init functions */
> +static int __init omap44xx_voltage_early_init(void)
> +{
> + ? ? ? s16 prm_mod = OMAP4430_PRM_DEVICE_INST;
> + ? ? ? s16 prm_irqst_ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
> +
> + ? ? ? if (!cpu_is_omap44xx())
> + ? ? ? ? ? ? ? return 0;
> +
> + ? ? ? /*
> + ? ? ? ?* XXX Will depend on the process, validation, and binning
> + ? ? ? ?* for the currently-running IC
> + ? ? ? ?*/
> + ? ? ? omap4_vdd_mpu_info.volt_data = omap44xx_vdd_mpu_volt_data;
> + ? ? ? omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;
> + ? ? ? omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data;
> +
> + ? ? ? return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?omap4_vdd_info,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ARRAY_SIZE(omap4_vdd_info));
> +};
> +core_initcall(omap44xx_voltage_early_init);
> diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h
> new file mode 100644
> index 0000000..7ce134f
> --- /dev/null
> +++ b/arch/arm/mach-omap2/vp.h
> @@ -0,0 +1,143 @@
> +/*
> + * OMAP3/4 Voltage Processor (VP) structure and macro definitions
> + *
> + * Copyright (C) 2007, 2010 Texas Instruments, Inc.
> + * Rajendra Nayak <rnayak@ti.com>
> + * Lesly A M <x0080970@ti.com>
> + * Thara Gopinath <thara@ti.com>
> + *
> + * Copyright (C) 2008, 2011 Nokia Corporation
> + * Kalle Jokiniemi
> + * Paul Walmsley
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + */
> +#ifndef __ARCH_ARM_MACH_OMAP2_VP_H
> +#define __ARCH_ARM_MACH_OMAP2_VP_H
> +
> +#include <linux/kernel.h>
> +
> +/* XXX document */
> +#define VP_IDLE_TIMEOUT ? ? ? ? ? ? ? ?200
> +#define VP_TRANXDONE_TIMEOUT ? 300
> +
> +
> +/**
> + * struct omap_vp_common_data - register data common to all VDDs
> + * @vpconfig_errorgain_mask: ERRORGAIN bitmask in the PRM_VP*_CONFIG reg
> + * @vpconfig_initvoltage_mask: INITVOLTAGE bitmask in the PRM_VP*_CONFIG reg
> + * @vpconfig_timeouten_mask: TIMEOUT bitmask in the PRM_VP*_CONFIG reg
> + * @vpconfig_initvdd: INITVDD bitmask in the PRM_VP*_CONFIG reg
> + * @vpconfig_forceupdate: FORCEUPDATE bitmask in the PRM_VP*_CONFIG reg
> + * @vpconfig_vpenable: VPENABLE bitmask in the PRM_VP*_CONFIG reg
> + * @vpconfig_erroroffset_shift: ERROROFFSET field shift in PRM_VP*_CONFIG reg
> + * @vpconfig_errorgain_shift: ERRORGAIN field shift in PRM_VP*_CONFIG reg
> + * @vpconfig_initvoltage_shift: INITVOLTAGE field shift in PRM_VP*_CONFIG reg
> + * @vpconfig_stepmin_shift: VSTEPMIN field shift in the PRM_VP*_VSTEPMIN reg
> + * @vpconfig_smpswaittimemin_shift: SMPSWAITTIMEMIN field shift in PRM_VP*_VSTEPMIN reg
> + * @vpconfig_stepmax_shift: VSTEPMAX field shift in the PRM_VP*_VSTEPMAX reg
> + * @vpconfig_smpswaittimemax_shift: SMPSWAITTIMEMAX field shift in PRM_VP*_VSTEPMAX reg
> + * @vpconfig_vlimitto_vddmin_shift: VDDMIN field shift in PRM_VP*_VLIMITTO reg
> + * @vpconfig_vlimitto_vddmax_shift: VDDMAX field shift in PRM_VP*_VLIMITTO reg
> + * @vpconfig_vlimitto_timeout_shift: TIMEOUT field shift in PRM_VP*_VLIMITTO reg
> + *
> + * XXX It it not necessary to have both a mask and a shift for the same
> + * ? ? bitfield - remove one
> + * XXX Many of these fields are wrongly named -- e.g., vpconfig_smps* -- fix!
> + */
> +struct omap_vp_common_data {
> + ? ? ? u32 vpconfig_errorgain_mask;
> + ? ? ? u32 vpconfig_initvoltage_mask;
> + ? ? ? u32 vpconfig_timeouten;
> + ? ? ? u32 vpconfig_initvdd;
> + ? ? ? u32 vpconfig_forceupdate;
> + ? ? ? u32 vpconfig_vpenable;
> + ? ? ? u8 vpconfig_erroroffset_shift;
> + ? ? ? u8 vpconfig_errorgain_shift;
> + ? ? ? u8 vpconfig_initvoltage_shift;
> + ? ? ? u8 vstepmin_stepmin_shift;
> + ? ? ? u8 vstepmin_smpswaittimemin_shift;
> + ? ? ? u8 vstepmax_stepmax_shift;
> + ? ? ? u8 vstepmax_smpswaittimemax_shift;
> + ? ? ? u8 vlimitto_vddmin_shift;
> + ? ? ? u8 vlimitto_vddmax_shift;
> + ? ? ? u8 vlimitto_timeout_shift;
> +};
> +
> +/**
> + * struct omap_vp_prm_irqst_data - PRM_IRQSTATUS_MPU.VP_TRANXDONE_ST data
> + * @prm_irqst_reg: reg offset for PRM_IRQSTATUS_MPU from top of PRM
> + * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
> + *
> + * XXX prm_irqst_reg does not belong here
> + * XXX Note that on OMAP3, VP_TRANXDONE interrupt may not work due to a
> + * ? ? hardware bug
> + * XXX This structure is probably not needed
> + */
> +struct omap_vp_prm_irqst_data {
> + ? ? ? u8 prm_irqst_reg;
> + ? ? ? u32 tranxdone_status;
> +};
> +
> +/**
> + * struct omap_vp_instance_data - VP register offsets (per-VDD)
> + * @vp_common: pointer to struct omap_vp_common_data * for this SoC
> + * @prm_irqst_data: pointer to struct omap_vp_prm_irqst_data for this VDD
> + * @vpconfig: PRM_VP*_CONFIG reg offset from PRM start
> + * @vstepmin: PRM_VP*_VSTEPMIN reg offset from PRM start
> + * @vlimitto: PRM_VP*_VLIMITTO reg offset from PRM start
> + * @vstatus: PRM_VP*_VSTATUS reg offset from PRM start
> + * @voltage: PRM_VP*_VOLTAGE reg offset from PRM start
> + *
> + * XXX vp_common is probably not needed since it is per-SoC
> + */
> +struct omap_vp_instance_data {
> + ? ? ? const struct omap_vp_common_data *vp_common;
> + ? ? ? const struct omap_vp_prm_irqst_data *prm_irqst_data;
> + ? ? ? u8 vpconfig;
> + ? ? ? u8 vstepmin;
> + ? ? ? u8 vstepmax;
> + ? ? ? u8 vlimitto;
> + ? ? ? u8 vstatus;
> + ? ? ? u8 voltage;
> +};
> +
> +/**
> + * struct omap_vp_runtime_data - VP data populated at runtime by code
> + * @vpconfig_erroroffset: value of ERROROFFSET bitfield in PRM_VP*_CONFIG
> + * @vpconfig_errorgain: value of ERRORGAIN bitfield in PRM_VP*_CONFIG
> + * @vstepmin_smpswaittimemin: value of SMPSWAITTIMEMIN bitfield in PRM_VP*_VSTEPMIN
> + * @vstepmax_smpswaittimemax: value of SMPSWAITTIMEMAX bitfield in PRM_VP*_VSTEPMAX
> + * @vlimitto_timeout: value of TIMEOUT bitfield in PRM_VP*_VLIMITTO
> + * @vstepmin_stepmin: value of VSTEPMIN bitfield in PRM_VP*_VSTEPMIN
> + * @vstepmax_stepmax: value of VSTEPMAX bitfield in PRM_VP*_VSTEPMAX
> + * @vlimitto_vddmin: value of VDDMIN bitfield in PRM_VP*_VLIMITTO
> + * @vlimitto_vddmax: value of VDDMAX bitfield in PRM_VP*_VLIMITTO
> + *
> + * XXX Is this structure really needed? ?Why not just program the
> + * device directly? ?They are in PRM space, therefore in the WKUP
> + * powerdomain, so register contents should not be lost in off-mode.
> + * XXX Some of these fields are incorrectly named, e.g., vstep*
> + */
> +struct omap_vp_runtime_data {
> + ? ? ? u32 vpconfig_erroroffset;
> + ? ? ? u16 vpconfig_errorgain;
> + ? ? ? u16 vstepmin_smpswaittimemin;
> + ? ? ? u16 vstepmax_smpswaittimemax;
> + ? ? ? u16 vlimitto_timeout;
> + ? ? ? u8 vstepmin_stepmin;
> + ? ? ? u8 vstepmax_stepmax;
> + ? ? ? u8 vlimitto_vddmin;
> + ? ? ? u8 vlimitto_vddmax;
> +};
> +
> +extern struct omap_vp_instance_data omap3_vp1_data;
> +extern struct omap_vp_instance_data omap3_vp2_data;
> +
> +extern struct omap_vp_instance_data omap4_vp_mpu_data;
> +extern struct omap_vp_instance_data omap4_vp_iva_data;
> +extern struct omap_vp_instance_data omap4_vp_core_data;
> +
> +#endif
> diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c
> new file mode 100644
> index 0000000..6452170
> --- /dev/null
> +++ b/arch/arm/mach-omap2/vp3xxx_data.c
> @@ -0,0 +1,82 @@
> +/*
> + * OMAP3 Voltage Processor (VP) data
> + *
> + * Copyright (C) 2007, 2010 Texas Instruments, Inc.
> + * Rajendra Nayak <rnayak@ti.com>
> + * Lesly A M <x0080970@ti.com>
> + * Thara Gopinath <thara@ti.com>
> + *
> + * Copyright (C) 2008, 2011 Nokia Corporation
> + * Kalle Jokiniemi
> + * Paul Walmsley
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +
> +#include <plat/common.h>
> +
> +#include "prm-regbits-34xx.h"
> +#include "voltage.h"
> +
> +#include "vp.h"
> +
> +/*
> + * VP data common to 34xx/36xx chips
> + * XXX This stuff presumably belongs in the vp3xxx.c or vp.c file.
> + */
> +static const struct omap_vp_common_data omap3_vp_common = {
> + ? ? ? .vpconfig_erroroffset_shift = OMAP3430_ERROROFFSET_SHIFT,
> + ? ? ? .vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK,
> + ? ? ? .vpconfig_errorgain_shift = OMAP3430_ERRORGAIN_SHIFT,
> + ? ? ? .vpconfig_initvoltage_shift = OMAP3430_INITVOLTAGE_SHIFT,
> + ? ? ? .vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK,
> + ? ? ? .vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK,
> + ? ? ? .vpconfig_initvdd = OMAP3430_INITVDD_MASK,
> + ? ? ? .vpconfig_forceupdate = OMAP3430_FORCEUPDATE_MASK,
> + ? ? ? .vpconfig_vpenable = OMAP3430_VPENABLE_MASK,
> + ? ? ? .vstepmin_smpswaittimemin_shift = OMAP3430_SMPSWAITTIMEMIN_SHIFT,
> + ? ? ? .vstepmax_smpswaittimemax_shift = OMAP3430_SMPSWAITTIMEMAX_SHIFT,
> + ? ? ? .vstepmin_stepmin_shift = OMAP3430_VSTEPMIN_SHIFT,
> + ? ? ? .vstepmax_stepmax_shift = OMAP3430_VSTEPMAX_SHIFT,
> + ? ? ? .vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT,
> + ? ? ? .vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT,
> + ? ? ? .vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT,
> +};
> +
> +static const struct omap_vp_prm_irqst_data omap3_vp1_prm_irqst_data = {
> + ? ? ? .prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
> + ? ? ? .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
> +};
> +
> +struct omap_vp_instance_data omap3_vp1_data = {
> + ? ? ? .vp_common = &omap3_vp_common,
> + ? ? ? .vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET,
> + ? ? ? .vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
> + ? ? ? .vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
> + ? ? ? .vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
> + ? ? ? .vstatus = OMAP3_PRM_VP1_STATUS_OFFSET,
> + ? ? ? .voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
> + ? ? ? .prm_irqst_data = &omap3_vp1_prm_irqst_data,
> +};
> +
> +static const struct omap_vp_prm_irqst_data omap3_vp2_prm_irqst_data = {
> + ? ? ? .prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
> + ? ? ? .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
> +};
> +
> +struct omap_vp_instance_data omap3_vp2_data = {
> + ? ? ? .vp_common = &omap3_vp_common,
> + ? ? ? .vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET,
> + ? ? ? .vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
> + ? ? ? .vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
> + ? ? ? .vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
> + ? ? ? .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
> + ? ? ? .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
> + ? ? ? .prm_irqst_data = &omap3_vp2_prm_irqst_data,
> +};
> diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c
> new file mode 100644
> index 0000000..7b26f75
> --- /dev/null
> +++ b/arch/arm/mach-omap2/vp44xx_data.c
> @@ -0,0 +1,97 @@
> +/*
> + * OMAP3 Voltage Processor (VP) data
> + *
> + * Copyright (C) 2007, 2010 Texas Instruments, Inc.
> + * Rajendra Nayak <rnayak@ti.com>
> + * Lesly A M <x0080970@ti.com>
> + * Thara Gopinath <thara@ti.com>
> + *
> + * Copyright (C) 2008, 2011 Nokia Corporation
> + * Kalle Jokiniemi
> + * Paul Walmsley
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +
> +#include <plat/common.h>
> +
> +#include "prm44xx.h"
> +#include "prm-regbits-44xx.h"
> +#include "voltage.h"
> +
> +#include "vp.h"
> +
> +/*
> + * VP data common to 44xx chips
> + * XXX This stuff presumably belongs in the vp44xx.c or vp.c file.
> + */
> +static const struct omap_vp_common_data omap4_vp_data = {
> + ? ? ? .vpconfig_erroroffset_shift = OMAP4430_ERROROFFSET_SHIFT,
> + ? ? ? .vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK,
> + ? ? ? .vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT,
> + ? ? ? .vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT,
> + ? ? ? .vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK,
> + ? ? ? .vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK,
> + ? ? ? .vpconfig_initvdd = OMAP4430_INITVDD_MASK,
> + ? ? ? .vpconfig_forceupdate = OMAP4430_FORCEUPDATE_MASK,
> + ? ? ? .vpconfig_vpenable = OMAP4430_VPENABLE_MASK,
> + ? ? ? .vstepmin_smpswaittimemin_shift = OMAP4430_SMPSWAITTIMEMIN_SHIFT,
> + ? ? ? .vstepmax_smpswaittimemax_shift = OMAP4430_SMPSWAITTIMEMAX_SHIFT,
> + ? ? ? .vstepmin_stepmin_shift = OMAP4430_VSTEPMIN_SHIFT,
> + ? ? ? .vstepmax_stepmax_shift = OMAP4430_VSTEPMAX_SHIFT,
> + ? ? ? .vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT,
> + ? ? ? .vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT,
> + ? ? ? .vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT,
> +};
> +
> +static const struct omap_vp_prm_irqst_data omap4_vp_mpu_prm_irqst_data = {
> + ? ? ? .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
> + ? ? ? .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
> +};
> +
> +struct omap_vp_instance_data omap4_vp_mpu_data = {
> + ? ? ? .vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
> + ? ? ? .vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
> + ? ? ? .vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
> + ? ? ? .vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
> + ? ? ? .vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
> + ? ? ? .voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
> + ? ? ? .prm_irqst_data = &omap4_vp_mpu_prm_irqst_data,
> +};
> +
> +static const struct omap_vp_prm_irqst_data omap4_vp_iva_prm_irqst_data = {
> + ? ? ? .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
> + ? ? ? .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
> +};
> +
> +struct omap_vp_instance_data omap4_vp_iva_data = {
> + ? ? ? .vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
> + ? ? ? .vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
> + ? ? ? .vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
> + ? ? ? .vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
> + ? ? ? .vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
> + ? ? ? .voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
> + ? ? ? .prm_irqst_data = &omap4_vp_iva_prm_irqst_data,
> +};
> +
> +static const struct omap_vp_prm_irqst_data omap4_vp_core_prm_irqst_data = {
> + ? ? ? .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
> + ? ? ? .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
> +};
> +
> +struct omap_vp_instance_data omap4_vp_core_data = {
> + ? ? ? .vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
> + ? ? ? .vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
> + ? ? ? .vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
> + ? ? ? .vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
> + ? ? ? .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
> + ? ? ? .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
> + ? ? ? .prm_irqst_data = &omap4_vp_core_prm_irqst_data,
> +};
> +
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>
--
Thanks,
Regards,
Shweta
^ permalink raw reply
* [PATCH resend] omap: rx51: Add SI4713 FM transmitter
From: Jarkko Nikula @ 2011-02-21 7:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTikR5v9_G3oyRjVP1oCcBo=hU+ikywximd=VDbDd@mail.gmail.com>
On Mon, 21 Feb 2011 13:10:59 +0530
"Varadarajan, Charulatha" <charu@ti.com> wrote:
> > + ? ? ? err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
> > + ? ? ? if (err) {
> > + ? ? ? ? ? ? ? printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
>
> use pr_err instead of printk.
>
Thanks, I was obviously blind, will send an update :-)
--
Jarkko
^ permalink raw reply
* [PATCH v2 15/21] ARM: tegra: clock: Round rate before setting rate
From: Colin Cross @ 2011-02-21 7:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=jJRhyMZXbs3Unr-U+J59rt4SxMQtT4KtCqWbe@mail.gmail.com>
On Sun, Feb 20, 2011 at 8:19 PM, Olof Johansson <olof@lixom.net> wrote:
> Hi,
>
> On Sat, Feb 19, 2011 at 2:26 PM, Colin Cross <ccross@android.com> wrote:
>
>> diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
>> index 8d01a49..9798585 100644
>> --- a/arch/arm/mach-tegra/clock.c
>> +++ b/arch/arm/mach-tegra/clock.c
>> @@ -86,6 +86,7 @@ static unsigned long clk_predict_rate_from_parent(struct clk *c, struct clk *p)
>>
>> ? ? ? ?if (c->mul != 0 && c->div != 0) {
>> ? ? ? ? ? ? ? ?rate *= c->mul;
>> + ? ? ? ? ? ? ? rate += c->div / 2; /* round up */
>
> Shouldn't this be "rate += c->div - 1;"?
Yes, will fix
^ permalink raw reply
* [PATCH resend] omap: rx51: Add SI4713 FM transmitter
From: Varadarajan, Charulatha @ 2011-02-21 7:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298270556-11571-1-git-send-email-jhnikula@gmail.com>
On Mon, Feb 21, 2011 at 12:12, Jarkko Nikula <jhnikula@gmail.com> wrote:
> Add SI4713 FM transmitter supplies, platform data and setup to RX-51/N900.
> It is connected to line output signals of TLV320AIC34 codec A part.
> Driver can be either built-in or a module. It can be tuned with v4l2-ctl
> from ivtv-utils. Following examples illustrate the use of it:
>
> ? ? ? ?v4l2-ctl -d /dev/radio0 --set-ctrl=mute=0 (power up)
> ? ? ? ?v4l2-ctl -d /dev/radio0 -f 107900 (tune 107.9 MHz)
>
> ? ? ? ?v4l2-ctl -d /dev/radio0 --set-ctrl=mute=1 (power down)
>
> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>
> ---
> Resend = forgot to cc LAKML.
> ---
<<snip>>
> +
> +static __init void rx51_init_si4713(void)
> +{
> + ? ? ? int err;
> +
> + ? ? ? err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
> + ? ? ? if (err) {
> + ? ? ? ? ? ? ? printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
use pr_err instead of printk.
> + ? ? ? ? ? ? ? return;
> + ? ? ? }
> + ? ? ? rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ);
> + ? ? ? platform_device_register(&rx51_si4713_dev);
> +}
> +
<<snip>>
^ permalink raw reply
* [linux-pm] [PATCH] amba: move to pm ops
From: Rabin Vincent @ 2011-02-21 7:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <s5hr5b6wo7z.wl%tiwai@suse.de>
On Thu, Feb 17, 2011 at 23:14, Takashi Iwai <tiwai@suse.de> wrote:
> At Thu, 17 Feb 2011 13:19:46 +0530,
> Rabin Vincent wrote:
>>
>> Support pm_ops in the AMBA bus instead of the legacy ops. ? pm_ops is needed
>> for runtime pm, and there is also a general move to convert drivers to
>> dev_pm_ops rather than bus specific PM ops in order to facilitate core
>> development.
>>
>> Since there are only 6 AMBA drivers using suspend/resume, convert them all in
>> one go and directly use the GENERIC_SUBSYS_PM_OPS in the bus.
>>
>> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
>> Cc: Chris Ball <cjb@laptop.org>
>> Cc: Grant Likely <grant.likely@secretlab.ca>
>> Cc: Takashi Iwai <tiwai@suse.de>
>> Cc: Linus Walleij <linus.walleij@linaro.org>
>> Cc: Greg Kroah-Hartman <gregkh@suse.de>
>> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
>
> For sound/arm/aaci.c,
>
> ?Acked-by: Takashi Iwai <tiwai@suse.de>
>
> Though, this would result in a zero-filled *_pm struct when
> CONFIG_PM_* isn't set? ?It's a few bytes wastes ;)
Thank you for the ack. However, in v2 of the patch I've done a
different implementation in the bus code that doesn't necessitate
the conversion of all the drivers together, so this part is
dropped. I will take this comment into consideration if I do
end up converting all the drivers. Thanks.
^ permalink raw reply
* [PATCH v2 14/21] ARM: tegra: clock: Refcount periph clock enables
From: Colin Cross @ 2011-02-21 7:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTin8AmjM2CWoNh54NmyV6=298bGzDUPO+j4LTrBj@mail.gmail.com>
On Sun, Feb 20, 2011 at 8:18 PM, Olof Johansson <olof@lixom.net> wrote:
> Hi,
>
> On Sat, Feb 19, 2011 at 2:26 PM, Colin Cross <ccross@android.com> wrote:
>> Some peripheral clocks share enable bits. ?Refcount the enables so
>> that calling clk_disable on one clock will not turn off another
>> clock.
>>
>> Signed-off-by: Colin Cross <ccross@android.com>
>> ---
>> ?arch/arm/mach-tegra/tegra2_clocks.c | ? 35 +++++++++++++++++++++++++++++------
>> ?1 files changed, 29 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
>> index 196c249..2734889 100644
>> --- a/arch/arm/mach-tegra/tegra2_clocks.c
>> +++ b/arch/arm/mach-tegra/tegra2_clocks.c
>> @@ -154,6 +154,12 @@ static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
>> ?*/
>> ?static DEFINE_SPINLOCK(clock_register_lock);
>>
>> +/*
>> + * Some peripheral clocks share an enable bit, so refcount the enable bits
>> + * in registers CLK_ENABLE_L, CLK_ENABLE_H, and CLK_ENABLE_U
>> + */
>> +static int tegra_periph_clk_enable_refcount[3 * 32];
>
> Given that this is always locked when incrementing/decrementing,
> should it just be switched to an array of atomics instead?
No, the spinlock needs to be held between the increment/decrement and
test and the actual register write. The spinlock release in the
enable function needs to be moved after the register write.
^ permalink raw reply
* [PATCHv2] amba: support pm ops
From: Rabin Vincent @ 2011-02-21 7:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297928986-31171-1-git-send-email-rabin.vincent@stericsson.com>
Support pm_ops in the AMBA bus, required to allow drivers to use runtime pm.
The implementation of AMBA bus pm ops is based on the platform bus
implementation.
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
---
v2: Base the implementation on the platform bus instead of the generic ops,
implementation all the functions platform does and with the same behaviour.
Also continue to support the legacy operations so that this patch doesn't
need to modify all the drivers and thus becomes easier to merge.
drivers/amba/bus.c | 329 ++++++++++++++++++++++++++++++++++++++++++----
include/linux/amba/bus.h | 2 +
2 files changed, 308 insertions(+), 23 deletions(-)
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index ca96b0a..7bc7762 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -13,12 +13,12 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/io.h>
+#include <linux/pm.h>
#include <linux/amba/bus.h>
#include <asm/irq.h>
#include <asm/sizes.h>
-#define to_amba_device(d) container_of(d, struct amba_device, dev)
#define to_amba_driver(d) container_of(d, struct amba_driver, drv)
static struct amba_id *
@@ -57,26 +57,6 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
#define amba_uevent NULL
#endif
-static int amba_suspend(struct device *dev, pm_message_t state)
-{
- struct amba_driver *drv = to_amba_driver(dev->driver);
- int ret = 0;
-
- if (dev->driver && drv->suspend)
- ret = drv->suspend(to_amba_device(dev), state);
- return ret;
-}
-
-static int amba_resume(struct device *dev)
-{
- struct amba_driver *drv = to_amba_driver(dev->driver);
- int ret = 0;
-
- if (dev->driver && drv->resume)
- ret = drv->resume(to_amba_device(dev));
- return ret;
-}
-
#define amba_attr_func(name,fmt,arg...) \
static ssize_t name##_show(struct device *_dev, \
struct device_attribute *attr, char *buf) \
@@ -102,6 +82,310 @@ static struct device_attribute amba_dev_attrs[] = {
__ATTR_NULL,
};
+#ifdef CONFIG_PM_SLEEP
+
+static int amba_legacy_suspend(struct device *dev, pm_message_t mesg)
+{
+ struct amba_driver *adrv = to_amba_driver(dev->driver);
+ struct amba_device *adev = to_amba_device(dev);
+ int ret = 0;
+
+ if (dev->driver && adrv->suspend)
+ ret = adrv->suspend(adev, mesg);
+
+ return ret;
+}
+
+static int amba_legacy_resume(struct device *dev)
+{
+ struct amba_driver *adrv = to_amba_driver(dev->driver);
+ struct amba_device *adev = to_amba_device(dev);
+ int ret = 0;
+
+ if (dev->driver && adrv->resume)
+ ret = adrv->resume(adev);
+
+ return ret;
+}
+
+static int amba_pm_prepare(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (drv && drv->pm && drv->pm->prepare)
+ ret = drv->pm->prepare(dev);
+
+ return ret;
+}
+
+static void amba_pm_complete(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+
+ if (drv && drv->pm && drv->pm->complete)
+ drv->pm->complete(dev);
+}
+
+#else /* !CONFIG_PM_SLEEP */
+
+#define amba_pm_prepare NULL
+#define amba_pm_complete NULL
+
+#endif /* !CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_SUSPEND
+
+static int amba_pm_suspend(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->suspend)
+ ret = drv->pm->suspend(dev);
+ } else {
+ ret = amba_legacy_suspend(dev, PMSG_SUSPEND);
+ }
+
+ return ret;
+}
+
+static int amba_pm_suspend_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->suspend_noirq)
+ ret = drv->pm->suspend_noirq(dev);
+ }
+
+ return ret;
+}
+
+static int amba_pm_resume(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->resume)
+ ret = drv->pm->resume(dev);
+ } else {
+ ret = amba_legacy_resume(dev);
+ }
+
+ return ret;
+}
+
+static int amba_pm_resume_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->resume_noirq)
+ ret = drv->pm->resume_noirq(dev);
+ }
+
+ return ret;
+}
+
+#else /* !CONFIG_SUSPEND */
+
+#define amba_pm_suspend NULL
+#define amba_pm_resume NULL
+#define amba_pm_suspend_noirq NULL
+#define amba_pm_resume_noirq NULL
+
+#endif /* !CONFIG_SUSPEND */
+
+#ifdef CONFIG_HIBERNATION
+
+static int amba_pm_freeze(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->freeze)
+ ret = drv->pm->freeze(dev);
+ } else {
+ ret = amba_legacy_suspend(dev, PMSG_FREEZE);
+ }
+
+ return ret;
+}
+
+static int amba_pm_freeze_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->freeze_noirq)
+ ret = drv->pm->freeze_noirq(dev);
+ }
+
+ return ret;
+}
+
+static int amba_pm_thaw(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->thaw)
+ ret = drv->pm->thaw(dev);
+ } else {
+ ret = amba_legacy_resume(dev);
+ }
+
+ return ret;
+}
+
+static int amba_pm_thaw_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->thaw_noirq)
+ ret = drv->pm->thaw_noirq(dev);
+ }
+
+ return ret;
+}
+
+static int amba_pm_poweroff(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->poweroff)
+ ret = drv->pm->poweroff(dev);
+ } else {
+ ret = amba_legacy_suspend(dev, PMSG_HIBERNATE);
+ }
+
+ return ret;
+}
+
+static int amba_pm_poweroff_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->poweroff_noirq)
+ ret = drv->pm->poweroff_noirq(dev);
+ }
+
+ return ret;
+}
+
+static int amba_pm_restore(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->restore)
+ ret = drv->pm->restore(dev);
+ } else {
+ ret = amba_legacy_resume(dev);
+ }
+
+ return ret;
+}
+
+static int amba_pm_restore_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->restore_noirq)
+ ret = drv->pm->restore_noirq(dev);
+ }
+
+ return ret;
+}
+
+#else /* !CONFIG_HIBERNATION */
+
+#define amba_pm_freeze NULL
+#define amba_pm_thaw NULL
+#define amba_pm_poweroff NULL
+#define amba_pm_restore NULL
+#define amba_pm_freeze_noirq NULL
+#define amba_pm_thaw_noirq NULL
+#define amba_pm_poweroff_noirq NULL
+#define amba_pm_restore_noirq NULL
+
+#endif /* !CONFIG_HIBERNATION */
+
+static const struct dev_pm_ops amba_pm = {
+ .prepare = amba_pm_prepare,
+ .complete = amba_pm_complete,
+ .suspend = amba_pm_suspend,
+ .resume = amba_pm_resume,
+ .freeze = amba_pm_freeze,
+ .thaw = amba_pm_thaw,
+ .poweroff = amba_pm_poweroff,
+ .restore = amba_pm_restore,
+ .suspend_noirq = amba_pm_suspend_noirq,
+ .resume_noirq = amba_pm_resume_noirq,
+ .freeze_noirq = amba_pm_freeze_noirq,
+ .thaw_noirq = amba_pm_thaw_noirq,
+ .poweroff_noirq = amba_pm_poweroff_noirq,
+ .restore_noirq = amba_pm_restore_noirq,
+ SET_RUNTIME_PM_OPS(
+ pm_generic_runtime_suspend,
+ pm_generic_runtime_resume,
+ pm_generic_runtime_idle
+ )
+};
+
/*
* Primecells are part of the Advanced Microcontroller Bus Architecture,
* so we call the bus "amba".
@@ -111,8 +395,7 @@ struct bus_type amba_bustype = {
.dev_attrs = amba_dev_attrs,
.match = amba_match,
.uevent = amba_uevent,
- .suspend = amba_suspend,
- .resume = amba_resume,
+ .pm = &amba_pm,
};
static int __init amba_init(void)
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index a0ccf28..1849975 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -58,6 +58,8 @@ enum amba_vendor {
extern struct bus_type amba_bustype;
+#define to_amba_device(d) container_of(d, struct amba_device, dev)
+
#define amba_get_drvdata(d) dev_get_drvdata(&d->dev)
#define amba_set_drvdata(d,p) dev_set_drvdata(&d->dev, p)
--
1.7.2.dirty
^ permalink raw reply related
* [PATCH v2 12/21] ARM: tegra: clock: Add shared bus clock type
From: Colin Cross @ 2011-02-21 7:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTinWQRmKhorYHQ2rHCArHN89go-2mYVAe5UUZVOV@mail.gmail.com>
On Sun, Feb 20, 2011 at 8:15 PM, Olof Johansson <olof@lixom.net> wrote:
> Hi,
>
> On Sat, Feb 19, 2011 at 2:25 PM, Colin Cross <ccross@android.com> wrote:
>> Some clocks may have multiple downstream users that need to request a
>> higher clock rate. ?Shared bus clocks provide a unique shared_bus_user
>> clock to each user. ?The frequency of the bus is set to the highest
>> enabled shared_bus_user clock, with a minimum value set by the
>> shared bus. ?Drivers can use clk_enable and clk_disable to enable
>> or disable their requirement, and clk_set_rate to set the minimum rate.
>>
>> Signed-off-by: Colin Cross <ccross@android.com>
>
> [...]
>> diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
>> index a1c86d8..dd53af3 100644
>> --- a/arch/arm/mach-tegra/tegra2_clocks.c
>> +++ b/arch/arm/mach-tegra/tegra2_clocks.c
> [...]
>
>> + ? ? ? c->u.shared_bus_user.rate = c->parent->max_rate;
>> + ? ? ? c->state = OFF;
>> +#ifdef CONFIG_DEBUG_FS
>> + ? ? ? c->set = 1;
>> +#endif
>> +
>> + ? ? ? spin_lock_irqsave(&c->parent->spinlock, flags);
>
>
> A later patch in the series removes the ifdef. Might as well remove it
> here. Also, should be c->set = true, which that patch also does. :)
At this point in the series c->set is not defined for
CONFIG_DEBUG_FS=n, so dropping the #ifdef would break bisection, and I
left the = 1 in for consistency.
> With that fixed:
>
> Acked-by: Olof Johansson <olof@lixom.net>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH v2 09/21] ARM: tegra: clock: Move unshared clk struct members into union
From: Colin Cross @ 2011-02-21 7:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=1Sxsa7ZwUSX6NK2M5Sp3Ww20CumCrividGsrx@mail.gmail.com>
On Sun, Feb 20, 2011 at 8:10 PM, Olof Johansson <olof@lixom.net> wrote:
> On Sat, Feb 19, 2011 at 2:25 PM, Colin Cross <ccross@android.com> wrote:
>> Signed-off-by: Colin Cross <ccross@android.com>
>
> Same here, short description. With that:
>
> Acked-by: Olof Johansson <olof@lixom.net>
>
I will add:
Creates a union of a struct for each type of clock to reduce memory
usage and clarify which members are used by all clocks and which are
used by a single type.
^ permalink raw reply
* [PATCH v2 03/21] ARM: tegra: clock: Drop debugging
From: Colin Cross @ 2011-02-21 6:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=MaoEqcOwnsvwWvPsUVFMYXfGsLR6zUbHMQ56R@mail.gmail.com>
On Sun, Feb 20, 2011 at 8:07 PM, Olof Johansson <olof@lixom.net> wrote:
> On Sat, Feb 19, 2011 at 2:25 PM, Colin Cross <ccross@android.com> wrote:
>> Signed-off-by: Colin Cross <ccross@android.com>
>
> Same here, I know the patch is obvious but just a one-liner in the
> patch description is common practice.
>
> Acked-by: Olof Johansson <olof@lixom.net>
I will add:
Drop the unnecessary pr_debug calls to avoid having to maintain them.
^ permalink raw reply
* [PATCH v2 02/21] ARM: tegra: clock: Don't BUG on changing an enabled PLL
From: Colin Cross @ 2011-02-21 6:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTimk5boeykToWCrosa5Q+Di5_uiOEU8tqh-aa0SE@mail.gmail.com>
On Sun, Feb 20, 2011 at 8:06 PM, Olof Johansson <olof@lixom.net> wrote:
> On Sat, Feb 19, 2011 at 2:25 PM, Colin Cross <ccross@android.com> wrote:
>> Signed-off-by: Colin Cross <ccross@android.com>
>
> Please add a 1-line description of why bugging doesn't make sense.
>
> Patch itself:
>
> Acked-by: Olof Johansson <olof@lixom.net>
>
I will add:
When updating the CPU PLL frequency, keeping the PLL enabled avoids
ramping the PLL all the way down and back up again. Remove the BUG_ON
in tegra2_pll_clk_set_rate to allow the rate to change while the PLL
is enabled.
^ permalink raw reply
* [PATCH resend] omap: rx51: Add SI4713 FM transmitter
From: Jarkko Nikula @ 2011-02-21 6:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298040354-1726-1-git-send-email-jhnikula@gmail.com>
Add SI4713 FM transmitter supplies, platform data and setup to RX-51/N900.
It is connected to line output signals of TLV320AIC34 codec A part.
Driver can be either built-in or a module. It can be tuned with v4l2-ctl
from ivtv-utils. Following examples illustrate the use of it:
v4l2-ctl -d /dev/radio0 --set-ctrl=mute=0 (power up)
v4l2-ctl -d /dev/radio0 -f 107900 (tune 107.9 MHz)
v4l2-ctl -d /dev/radio0 --set-ctrl=mute=1 (power down)
Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>
---
Resend = forgot to cc LAKML.
---
arch/arm/mach-omap2/board-rx51-peripherals.c | 44 ++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index e75e240..d0998f8 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -36,6 +36,8 @@
#include <sound/tlv320aic3x.h>
#include <sound/tpa6130a2-plat.h>
+#include <media/radio-si4713.h>
+#include <media/si4713.h>
#include <../drivers/staging/iio/light/tsl2563.h>
@@ -47,6 +49,8 @@
#define RX51_WL1251_POWER_GPIO 87
#define RX51_WL1251_IRQ_GPIO 42
+#define RX51_FMTX_RESET_GPIO 163
+#define RX51_FMTX_IRQ 53
/* list all spi devices here */
enum {
@@ -357,10 +361,14 @@ static struct regulator_consumer_supply rx51_vio_supplies[] = {
REGULATOR_SUPPLY("DVDD", "2-0018"),
REGULATOR_SUPPLY("IOVDD", "2-0019"),
REGULATOR_SUPPLY("DVDD", "2-0019"),
+ /* Si4713 IO supply */
+ REGULATOR_SUPPLY("vio", "2-0063"),
};
static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+ /* Si4713 supply */
+ REGULATOR_SUPPLY("vdd", "2-0063"),
};
static struct regulator_consumer_supply rx51_vdac_supply[] = {
@@ -511,6 +519,41 @@ static struct regulator_init_data rx51_vio = {
.consumer_supplies = rx51_vio_supplies,
};
+static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = {
+ .gpio_reset = RX51_FMTX_RESET_GPIO,
+};
+
+static struct i2c_board_info rx51_si4713_board_info __initdata_or_module = {
+ I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH),
+ .platform_data = &rx51_si4713_i2c_data,
+};
+
+static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = {
+ .i2c_bus = 2,
+ .subdev_board_info = &rx51_si4713_board_info,
+};
+
+static struct platform_device rx51_si4713_dev __initdata_or_module = {
+ .name = "radio-si4713",
+ .id = -1,
+ .dev = {
+ .platform_data = &rx51_si4713_data,
+ },
+};
+
+static __init void rx51_init_si4713(void)
+{
+ int err;
+
+ err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
+ if (err) {
+ printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
+ return;
+ }
+ rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ);
+ platform_device_register(&rx51_si4713_dev);
+}
+
static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
{
/* FIXME this gpio setup is just a placeholder for now */
@@ -921,6 +964,7 @@ void __init rx51_peripherals_init(void)
board_smc91x_init();
rx51_add_gpio_keys();
rx51_init_wl1251();
+ rx51_init_si4713();
spi_register_board_info(rx51_peripherals_spi_board_info,
ARRAY_SIZE(rx51_peripherals_spi_board_info));
--
1.7.2.3
^ permalink raw reply related
* [PATCH V5 30/63] ST SPEAr: Replacing SIZE macro's with actual required size
From: viresh kumar @ 2011-02-21 6:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110219180119.GR29493@n2100.arm.linux.org.uk>
On 02/19/2011 11:31 PM, Russell King - ARM Linux wrote:
> Same comments as the other patch changing to SZ_* macros. Where possible
> fold these changes into the patch(es) which add the original definitions
> rather than having patches which add stuff and then separate patches
> which rework those patches.
>
Ok.
> Could you do that and provide reworked patches please? I'll publish the
> branch I've merged stuff onto thus far (but note that it's 'unstable'),
> but note that it won't contain the bits I've merged into the 'fixes'
> branch.
Ok. I will surely do that.
Just one question, should i send these patches to mailing list again or
directly to tracker?
--
viresh
^ permalink raw reply
* [PATCH V5 29/63] ST SPEAr: Changing resource size of amba devices to SZ_4K
From: viresh kumar @ 2011-02-21 6:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110219175850.GQ29493@n2100.arm.linux.org.uk>
On 02/19/2011 11:28 PM, Russell King - ARM Linux wrote:
> This is another patch which should be reorganized - move the CLCD bits
> into the CLCD patch and arrange for it to be applied early on in the
> series.
Doesn't we need to drop CLCD patch for now?
--
viresh
^ permalink raw reply
* [PATCH] ARM: imx53_smd add uncompress print
From: Frank Li @ 2011-02-21 6:28 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
arch/arm/plat-mxc/include/mach/uncompress.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index b702884..7412558 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -112,6 +112,7 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
break;
case MACH_TYPE_MX53_EVK:
case MACH_TYPE_MX53_LOCO:
+ case MACH_TYPE_MX53_SMD:
uart_base = MX53_UART1_BASE_ADDR;
break;
default:
--
1.6.3.3
^ permalink raw reply related
* [PATCH V5 36/63] ST SPEAr : EMI (Extrenal Memory Interface) controller driver
From: Vipin Kumar @ 2011-02-21 6:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110219171320.GO29493@n2100.arm.linux.org.uk>
On 2/19/2011 10:43 PM, Russell King - ARM Linux wrote:
> On Thu, Jan 20, 2011 at 12:56:14PM +0530, Viresh Kumar wrote:
>> From: Vipin Kumar <vipin.kumar@st.com>
>
>
> Subject: [PATCH V5 36/63] ST SPEAr : EMI (Extrenal Memory Interface)
> controller driver
>
> "External"
>
Sorry!!
>> + clk = clk_get(NULL, "emi");
>
> What is the platform device pointer passed into this function? It seems
> unused - would using &pdev->dev here be appropriate? Possibly not as it
> seems to be the physmap device.
>
Yes, the platform device pointer is unused
I would remove it....
>> +void __init
>> +emi_init_board_info(struct platform_device *pdev, struct resource *resources,
>> + int res_num, struct mtd_partition *partitions,
>> + unsigned int nr_partitions, unsigned int width)
>> +{
>> + struct physmap_flash_data *emi_plat_data = dev_get_platdata(&pdev->dev);
>> +
>> + pdev->resource = resources;
>> + pdev->num_resources = res_num;
>> +
>> + if (partitions) {
>> + emi_plat_data->parts = partitions;
>> + emi_plat_data->nr_parts = nr_partitions;
>> + }
>> +
>> + emi_plat_data->width = width;
>> +}
>
> I don't see why this has to be code rather than in the platform specific
> files as static initializers.
The device is instantiated in the machine file and above information comes
from the board file. So we kept them this way.
> Also, you seem to be passing stuff like
> 'EMI_FLASH_WIDTH32' in for 'width', which seems very odd as this is the
> byte width. I don't see why you need #defined constants for this.
>
> It's waiting someone who doesn't realise that it has a proper meaning
> to change it to an enum or something like that.
>
> If you think the physmap flash API is lacking some definitions for this,
> please talk to the MTD people.
Yes. We shouldn't have created new macro's for this. Will be removed.
vipin
^ permalink raw reply
* [PATCH] picoxcell_crypto: add support for the picoxcell crypto engines
From: Herbert Xu @ 2011-02-21 5:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297776733-17816-1-git-send-email-jamie@jamieiles.com>
On Tue, Feb 15, 2011 at 01:32:13PM +0000, Jamie Iles wrote:
> Picochip picoXcell devices have two crypto engines, one targeted
> at IPSEC offload and the other at WCDMA layer 2 ciphering.
>
> v2: - use symbolic constants for key sizes etc
> - cleanup DDT generation
> - use strict_strtoul() for stat irq threshold
> - minor code cleanups
>
> Cc: Herbert Xu <herbert@gondor.apana.org.au>
> Signed-off-by: Jamie Iles <jamie@jamieiles.com>
Patch applied. Thanks Jamie!
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH 1/7] Add a mfd IPUv3 driver
From: Jason Chen @ 2011-02-21 5:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297865452-32181-2-git-send-email-s.hauer@pengutronix.de>
hi, Sascha,
I have few comments for this patch.
> +#define MX51_IPU_CHANNEL_CSI0 ? ? ? ? ? ? ? ? ? 0
> +#define MX51_IPU_CHANNEL_CSI1 ? ? ? ? ? ? ? ? ? 1
> +#define MX51_IPU_CHANNEL_CSI2 ? ? ? ? ? ? ? ? ? 2
> +#define MX51_IPU_CHANNEL_CSI3 ? ? ? ? ? ? ? ? ? 3
> +#define MX51_IPU_CHANNEL_MEM_BG_SYNC ? ? ? ? ? 23
> +#define MX51_IPU_CHANNEL_MEM_FG_SYNC ? ? ? ? ? 27
> +#define MX51_IPU_CHANNEL_MEM_DC_SYNC ? ? ? ? ? 28
> +#define MX51_IPU_CHANNEL_MEM_FG_SYNC_ALPHA ? ? 31
> +#define MX51_IPU_CHANNEL_MEM_DC_ASYNC ? ? ? ? ?41
> +#define MX51_IPU_CHANNEL_ROT_ENC_MEM ? ? ? ? ? 45
> +#define MX51_IPU_CHANNEL_ROT_VF_MEM ? ? ? ? ? ?46
> +#define MX51_IPU_CHANNEL_ROT_PP_MEM ? ? ? ? ? ?47
> +#define MX51_IPU_CHANNEL_ROT_ENC_MEM_OUT ? ? ? 48
> +#define MX51_IPU_CHANNEL_ROT_VF_MEM_OUT ? ? ? ? ? ? ? ?49
> +#define MX51_IPU_CHANNEL_ROT_PP_MEM_OUT ? ? ? ? ? ? ? ?50
> +#define MX51_IPU_CHANNEL_MEM_BG_SYNC_ALPHA ? ? 51
Had better use MX5_IPU as prefix because it's same value in MX5X.
> +
> + ? ? ? ipu_idmac_reg = ioremap(ipu_base + IPU_IDMAC_REG_BASE, PAGE_SIZE);
> + ? ? ? if (!ipu_idmac_reg) {
> + ? ? ? ? ? ? ? ret = -ENOMEM;
> + ? ? ? ? ? ? ? goto failed_ioremap2;
> + ? ? ? }
> +
> + ? ? ? ret = ipu_mipi_setup();
> + ? ? ? if (ret)
> + ? ? ? ? ? ? ? goto failed_mipi_setup;
I dont know what's the best way to do it, but I think you had better
consider mx53 platform, so maybe this mipi_setup function and also
below ipu hw reset could be set in platform data.
> +
> + ? ? ? ipu_clk = clk_get(&pdev->dev, "ipu");
> + ? ? ? if (IS_ERR(ipu_clk)) {
> + ? ? ? ? ? ? ? ret = PTR_ERR(ipu_clk);
> + ? ? ? ? ? ? ? dev_err(&pdev->dev, "clk_get failed with %d", ret);
> + ? ? ? ? ? ? ? goto failed_clk_get;
> + ? ? ? }
> +
> + ? ? ? ipu_get();
> +
> + ? ? ? ret = request_irq(irq1, ipu_irq_handler, IRQF_DISABLED, pdev->name,
> + ? ? ? ? ? ? ? ? ? ? ? &pdev->dev);
> + ? ? ? if (ret) {
> + ? ? ? ? ? ? ? dev_err(&pdev->dev, "request irq %d failed with: %d\n", irq1, ret);
> + ? ? ? ? ? ? ? goto failed_request_irq1;
> + ? ? ? }
> +
> + ? ? ? ret = request_irq(irq2, ipu_irq_handler, IRQF_DISABLED, pdev->name,
> + ? ? ? ? ? ? ? ? ? ? ? &pdev->dev);
> + ? ? ? if (ret) {
> + ? ? ? ? ? ? ? dev_err(&pdev->dev, "request irq %d failed with: %d\n", irq2, ret);
> + ? ? ? ? ? ? ? goto failed_request_irq2;
> + ? ? ? }
> +
> + ? ? ? ipu_reset();
^ permalink raw reply
* Question About Linux Memory Mapping
From: hong zhang @ 2011-02-21 5:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201102192122.53746.marek.vasut@gmail.com>
Drasko,
Command line can assign all physical memory or partial memory to kernel using one or few mem=. For example, if you have 1 GBytes memory with starting port at 0x80000000, and want to reserve 512M anywhere between 0x80000000 and 0xc0000000 saying at 0x90000000. Then command line should be
mem=256M at 0x80000000 mem=256M at 0xb0000000. At this format, kernel should not touch memory between 0x9000000 and 0xb0000000 and the memory can be used by other OS or firmware.
This is my understanding.
---henry
--- On Sat, 2/19/11, Marek Vasut <marek.vasut@gmail.com> wrote:
> From: Marek Vasut <marek.vasut@gmail.com>
> Subject: Re: Question About Linux Memory Mapping
> To: linux-arm at lists.infradead.org
> Cc: "Drasko DRASKOVIC" <drasko.draskovic@gmail.com>, linux-arm-kernel at lists.infradead.org
> Date: Saturday, February 19, 2011, 2:22 PM
> On Friday 18 February 2011 21:56:28
> Drasko DRASKOVIC wrote:
> > Hi all,
> > in the article Booting ARM Linux :
> > http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html
> > I can see that mem map is passed via ATAG_MEM.
> However, in the same
> > article it is mentioned that this information can also
> be passed via
> > kernel command line paramters,?
> mem=<size>[KM][,@<phys_offset>].
> >
> > However, this does not seem to be true, as "mem"
> command line
> > parameter seems to be formated like this : mem= n[KMG]
> (i.e. no
> > offset), regarding to this reference :
> > http://oreilly.com/linux/excerpts/9780596100797/kernel-boot-command-line-pa
> > rameter-reference.html. Seems like memmap should be
> used instead.
> >
> > I tried passing the parameters like memmap=
> n[KMG]@start[KMG] but that
> > had no effect at all - still the same amount of System
> Ram was read
> > from ATAGS and presented in the system via
> /proc/iomem.
> >
> > What I needed it to reserve 1MB region for one FIFO at
> the end of RAM
> > (or somewhere else)
> > and protect it from the kernel. I tried passing
> memmap=
> > n[KMG]$start[KMG], but that did not worn neither.
>
> What are you exactly trying to achieve ? btw. if you really
> need to make a hole
> in RAM, you should reserve a bootmem node maybe?
> >
> > So my questions are following :
> > 1) Why commandlines are ignored and ATAGS are given
> priority ?
> > 2) What is the most elegant way to protect one region
> in RAM :
> >? a) By giving less memory with ATAGS_MEM and thus
> making protected
> > region invisible to Linux, lying to it that RAM is
> smaller
> >? b) By changing somehow linker script
> >? c) By changing some configuration variables
> (which ?)
> >
> > Thanks for the answers and best regards,
> > Drasko
> >
> > _______________________________________________
> > linux-arm mailing list
> > linux-arm at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm
>
> _______________________________________________
> linux-arm mailing list
> linux-arm at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm
>
^ permalink raw reply
* [PATCH 2/3] OMAP: voltage: move plat/voltage.h to mach-omap2/voltage.h
From: Gulati, Shweta @ 2011-02-21 4:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110221020855.7598.95586.stgit@twilight.localdomain>
Hi,
On Mon, Feb 21, 2011 at 7:38 AM, Paul Walmsley <paul@pwsan.com> wrote:
> At this point in time, there's no reason for this header file to be in
> plat-omap/include/plat/voltage.h. ?It should not be included by device
> drivers, and the code that uses it is currently all under mach-omap2/.
>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> ---
> ?arch/arm/mach-omap2/omap_twl.c ? ? ? ? ? ? ? | ? ?2 +-
> ?arch/arm/mach-omap2/pm.c ? ? ? ? ? ? ? ? ? ? | ? ?2 +-
> ?arch/arm/mach-omap2/smartreflex.h ? ? ? ? ? ?| ? ?3 ++-
> ?arch/arm/mach-omap2/sr_device.c ? ? ? ? ? ? ?| ? ?2 +-
> ?arch/arm/mach-omap2/voltage.c ? ? ? ? ? ? ? ?| ? ?3 ++-
> ?arch/arm/mach-omap2/voltage.h ? ? ? ? ? ? ? ?| ? ?0
> ?arch/arm/plat-omap/include/plat/omap_hwmod.h | ? ?1 -
> ?7 files changed, 7 insertions(+), 6 deletions(-)
> ?rename arch/arm/{plat-omap/include/plat/voltage.h => mach-omap2/voltage.h} (100%)
>
> diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
> index 00e1d2b..ad8c18a 100644
> --- a/arch/arm/mach-omap2/omap_twl.c
> +++ b/arch/arm/mach-omap2/omap_twl.c
> @@ -18,7 +18,7 @@
> ?#include <linux/kernel.h>
> ?#include <linux/i2c/twl.h>
>
> -#include <plat/voltage.h>
> +#include "voltage.h"
Extra Blank Line
> ?#include "pm.h"
>
> diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
> index d5a102c..4baa674 100644
> --- a/arch/arm/mach-omap2/pm.c
> +++ b/arch/arm/mach-omap2/pm.c
> @@ -18,8 +18,8 @@
> ?#include <plat/omap-pm.h>
> ?#include <plat/omap_device.h>
> ?#include <plat/common.h>
> -#include <plat/voltage.h>
>
> +#include "voltage.h"
> ?#include "powerdomain.h"
> ?#include "clockdomain.h"
> ?#include "pm.h"
> diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
> index 6568c88..5f35b9e 100644
> --- a/arch/arm/mach-omap2/smartreflex.h
> +++ b/arch/arm/mach-omap2/smartreflex.h
> @@ -21,7 +21,8 @@
> ?#define __ASM_ARM_OMAP_SMARTREFLEX_H
>
> ?#include <linux/platform_device.h>
> -#include <plat/voltage.h>
> +
> +#include "voltage.h"
>
> ?/*
> ?* Different Smartreflex IPs version. The v1 is the 65nm version used in
> diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
> index a636604..10d3c5e 100644
> --- a/arch/arm/mach-omap2/sr_device.c
> +++ b/arch/arm/mach-omap2/sr_device.c
> @@ -23,9 +23,9 @@
> ?#include <linux/io.h>
>
> ?#include <plat/omap_device.h>
> -#include <plat/voltage.h>
>
> ?#include "smartreflex.h"
> +#include "voltage.h"
> ?#include "control.h"
> ?#include "pm.h"
>
> diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
> index 12be525..3c9bcdc 100644
> --- a/arch/arm/mach-omap2/voltage.c
> +++ b/arch/arm/mach-omap2/voltage.c
> @@ -26,7 +26,6 @@
> ?#include <linux/slab.h>
>
> ?#include <plat/common.h>
> -#include <plat/voltage.h>
>
> ?#include "prm-regbits-34xx.h"
> ?#include "prm-regbits-44xx.h"
> @@ -35,6 +34,8 @@
> ?#include "prminst44xx.h"
> ?#include "control.h"
Extra Blank line
> +#include "voltage.h"
> +
> ?#define VP_IDLE_TIMEOUT ? ? ? ? ? ? ? ?200
> ?#define VP_TRANXDONE_TIMEOUT ? 300
> ?#define VOLTAGE_DIR_SIZE ? ? ? 16
> diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/mach-omap2/voltage.h
> similarity index 100%
> rename from arch/arm/plat-omap/include/plat/voltage.h
> rename to arch/arm/mach-omap2/voltage.h
> diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> index 1eee85a..93beae2 100644
> --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
> +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> @@ -34,7 +34,6 @@
> ?#include <linux/ioport.h>
> ?#include <linux/spinlock.h>
> ?#include <plat/cpu.h>
> -#include <plat/voltage.h>
"voltage.h" is not added.
> ?struct omap_device;
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>
--
Thanks,
Regards,
Shweta
^ permalink raw reply
* [PATCH v2] i2c: tegra: Add i2c support
From: Olof Johansson @ 2011-02-21 4:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298250861-27094-1-git-send-email-ccross@android.com>
Hi,
Just a couple of minor nits. I wouldn't worry about respinning just
for these comments, but if you end up doing it for other feedback, see
below.
-Olof
On Sun, Feb 20, 2011 at 5:14 PM, Colin Cross <ccross@android.com> wrote:
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> new file mode 100644
> index 0000000..3921f66
> --- /dev/null
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -0,0 +1,700 @@
> +/*
> + * drivers/i2c/busses/i2c-tegra.c
> + *
> + * Copyright (C) 2010 Google, Inc.
2011?
[..]
> +/*
> + * i2c_writel and i2c_readl will offset the register if necessary to talk
> + * to the I2C block inside the DVC block
> + */
> +static unsigned long tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev,
> + ? ? ? unsigned long reg)
> +{
> + ? ? ? if (i2c_dev->is_dvc)
> + ? ? ? ? ? ? ? reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40;
> + ? ? ? return reg;
> +}
> +
> +static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
> + ? ? ? unsigned long reg)
> +{
> + ? ? ? writel(val, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
> +}
> +
> +static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)
> +{
> + ? ? ? return readl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
> +}
> +
> +static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
> + ? ? ? unsigned long reg, int len)
> +{
> + ? ? ? writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
> +}
> +
> +static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
> + ? ? ? unsigned long reg, int len)
> +{
> + ? ? ? readsl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
> +}
All of the above pass in i2c_dev to tegra_i2c_reg_addr, might as well
do the base addition in there.
> diff --git a/include/linux/i2c-tegra.h b/include/linux/i2c-tegra.h
> new file mode 100644
> index 0000000..9c85da4
> --- /dev/null
> +++ b/include/linux/i2c-tegra.h
> @@ -0,0 +1,25 @@
> +/*
> + * drivers/i2c/busses/i2c-tegra.c
> + *
> + * Copyright (C) 2010 Google, Inc.
2011?
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox