Merge "msm: display: Add Data lane swap setting to DSI platform data" into msm-3.0
diff --git a/Documentation/devicetree/bindings/spmi/msm-spmi.txt b/Documentation/devicetree/bindings/spmi/msm-spmi.txt
new file mode 100644
index 0000000..fa91514
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/msm-spmi.txt
@@ -0,0 +1,72 @@
+* SPMI
+
+The spmi Device Tree support interprets up to two levels of Device Tree
+topology. The first level is required and specifies only a slave address.
+The second level is optional and allows for the specification of different
+offsets within the same 16-bit address space underneath a particular SPMI
+slave ID. Within the second level, any number of address ranges can be
+associated with a particular device within that 16-bit range.
+
+First level
+
+Required properites :
+
+ - reg: SPMI Slave ID (0-15) with no size cell.
+ - compatible : "qcom," prefixed string to match against the driver.
+
+Recommended properties :
+
+ - interrupts : <a b c> where a is the slave ID, b is the peripheral ID,
+ c is the device interrupt number (0-7). Each device supports any arbitrary
+ number of interrupts.
+ - interrupt-parent : the phandle for the interrupt controller that
+ services interrupts for this device.
+
+Second level
+
+Required properties :
+ - spmi-dev-container: Used by the parser to understand that this is the second
+ level of the tree.
+ - reg: <a b> where a is < 65536 and b is a size. Each device supports an
+ arbitrary number of address ranges.
+ - compatible : "qcom," prefixed string to match against the driver.
+
+Recommended properties :
+
+ - interrupts : <a b c> where a is the slave ID, b is is the peripheral ID,
+ c is the device interrupt number (0-7). Each device supports any arbitrary
+ number of interrupts.
+ - interrupt-parent : the phandle for the interrupt controller that
+ services interrupts for this device.
+
+Example:
+
+/ {
+ qcom,spmi@fc4c0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&qpnpint>;
+ pmic8941@d {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xd>;
+ spmi-dev-container;
+
+ coincell@2800 {
+ compatible = "qcom,qpnp-coincell";
+ reg = <0x2800 0x4000>;
+ interrupts = <0xd 0x28 0x6 0xd 0x28 0x3>;
+
+ };
+ pon@800 {
+ compatible = "qcom,qpnp-pon";
+ reg = <0x800 0x4000>;
+ };
+ };
+ customer_dev@2 {
+ compatible = "qcom,qpnp-pon";
+ reg = <0x2>;
+ interrupts = <0x2 0x08 0x1 0x2 0x8 0x3>;
+ };
+ };
+};
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 860e2bf..eca2ffa 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -66,6 +66,7 @@
CONFIG_MSM_PIL_QDSP6V4=y
CONFIG_MSM_PIL_RIVA=y
CONFIG_MSM_PIL_TZAPPS=y
+CONFIG_MSM_PIL_GSS=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_MODEM_8960=y
CONFIG_MSM_LPASS_8960=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index eb4244f..18e9085 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -66,6 +66,7 @@
CONFIG_MSM_PIL_QDSP6V4=y
CONFIG_MSM_PIL_RIVA=y
CONFIG_MSM_PIL_TZAPPS=y
+CONFIG_MSM_PIL_GSS=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_MODEM_8960=y
CONFIG_MSM_LPASS_8960=y
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 761c29e..c3b841a 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -27,6 +27,7 @@
#include <asm/byteorder.h>
#include <asm/memory.h>
#include <asm/system.h>
+#include <mach/msm_rtb.h>
/*
* ISA I/O bus memory addresses are 1:1 with the physical address.
@@ -47,13 +48,85 @@
extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
-#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))
-#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
-#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
+/*
+ * There may be cases when clients don't want to support or can't support the
+ * logging. The appropriate functions can be used but clients should carefully
+ * consider why they can't support the logging.
+ */
-#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
-#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
-#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
+#define __raw_writeb_no_log(v, a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))
+#define __raw_writew_no_log(v, a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
+#define __raw_writel_no_log(v, a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
+
+#define __raw_writeb(v, a) ({ \
+ int _ret; \
+ void *_addr = (void *)(a); \
+ _ret = uncached_logk(LOGK_WRITEL, _addr); \
+ ETB_WAYPOINT; \
+ __raw_writeb_no_log(v, _addr); \
+ if (_ret) \
+ LOG_BARRIER; \
+ })
+
+#define __raw_writew(v, a) ({ \
+ int _ret; \
+ void *_addr = (void *)(a); \
+ _ret = uncached_logk(LOGK_WRITEL, _addr); \
+ ETB_WAYPOINT; \
+ __raw_writew_no_log(v, _addr); \
+ if (_ret) \
+ LOG_BARRIER; \
+ })
+
+#define __raw_writel(v, a) ({ \
+ int _ret; \
+ void *_addr = (void *)(a); \
+ _ret = uncached_logk(LOGK_WRITEL, _addr); \
+ ETB_WAYPOINT; \
+ __raw_writel_no_log(v, _addr); \
+ if (_ret) \
+ LOG_BARRIER; \
+ })
+
+#define __raw_readb_no_log(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
+#define __raw_readw_no_log(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
+#define __raw_readl_no_log(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
+
+#define __raw_readb(a) ({ \
+ unsigned char __a; \
+ void *_addr = (void *)(a); \
+ int _ret; \
+ _ret = uncached_logk(LOGK_READL, _addr); \
+ ETB_WAYPOINT; \
+ __a = __raw_readb_no_log(_addr);\
+ if (_ret) \
+ LOG_BARRIER; \
+ __a; \
+ })
+
+#define __raw_readw(a) ({ \
+ unsigned short __a; \
+ void *_addr = (void *)(a); \
+ int _ret; \
+ _ret = uncached_logk(LOGK_READL, _addr); \
+ ETB_WAYPOINT; \
+ __a = __raw_readw_no_log(_addr);\
+ if (_ret) \
+ LOG_BARRIER; \
+ __a; \
+ })
+
+#define __raw_readl(a) ({ \
+ unsigned int __a; \
+ void *_addr = (void *)(a); \
+ int _ret; \
+ _ret = uncached_logk(LOGK_READL, _addr); \
+ ETB_WAYPOINT; \
+ __a = __raw_readl_no_log(_addr);\
+ if (_ret) \
+ LOG_BARRIER; \
+ __a; \
+ })
/*
* Architecture ioremap implementation.
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 3f04ce0..904839b 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1705,6 +1705,13 @@
used to decrypt data and perform secure operations on the behalf of
the kernel.
+config MSM_PIL_GSS
+ tristate "GSS (Coretx A5) Boot Support"
+ depends on MSM_PIL
+ help
+ Support for booting and shutting down Cortex A5 processors which run
+ GPS subsystem firmware.
+
config MSM_SCM
bool "Secure Channel Manager (SCM) support"
default n
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 939b036..19a316e 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -71,6 +71,7 @@
obj-$(CONFIG_MSM_PIL_RIVA) += pil-riva.o
obj-$(CONFIG_MSM_PIL_TZAPPS) += pil-tzapps.o
obj-$(CONFIG_MSM_PIL_MODEM) += pil-modem.o
+obj-$(CONFIG_MSM_PIL_GSS) += pil-gss.o
obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
obj-$(CONFIG_ARCH_FSM9XXX) += sirc-fsm9xxx.o
obj-$(CONFIG_MSM_FIQ_SUPPORT) += fiq_glue.o
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 23d03ef..6140559 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -369,34 +369,39 @@
};
#ifdef CONFIG_CPU_FREQ_MSM
-static struct cpufreq_frequency_table freq_table[20];
+static struct cpufreq_frequency_table freq_table[NR_CPUS][20];
static void __init cpufreq_table_init(void)
{
- unsigned int i;
- unsigned int freq_cnt = 0;
+ int cpu;
+ for_each_possible_cpu(cpu) {
+ unsigned int i, freq_cnt = 0;
- /* Construct the freq_table table from acpu_freq_tbl since the
- * freq_table values need to match frequencies specified in
- * acpu_freq_tbl and acpu_freq_tbl needs to be fixed up during init.
- */
- for (i = 0; acpu_freq_tbl[i].a11clk_khz != 0
- && freq_cnt < ARRAY_SIZE(freq_table)-1; i++) {
- if (acpu_freq_tbl[i].use_for_scaling) {
- freq_table[freq_cnt].index = freq_cnt;
- freq_table[freq_cnt].frequency
- = acpu_freq_tbl[i].a11clk_khz;
- freq_cnt++;
+ /* Construct the freq_table table from acpu_freq_tbl since
+ * the freq_table values need to match frequencies specified
+ * in acpu_freq_tbl and acpu_freq_tbl needs to be fixed up
+ * during init.
+ */
+ for (i = 0; acpu_freq_tbl[i].a11clk_khz != 0
+ && freq_cnt < ARRAY_SIZE(*freq_table)-1; i++) {
+ if (acpu_freq_tbl[i].use_for_scaling) {
+ freq_table[cpu][freq_cnt].index = freq_cnt;
+ freq_table[cpu][freq_cnt].frequency
+ = acpu_freq_tbl[i].a11clk_khz;
+ freq_cnt++;
+ }
}
+
+ /* freq_table not big enough to store all usable freqs. */
+ BUG_ON(acpu_freq_tbl[i].a11clk_khz != 0);
+
+ freq_table[cpu][freq_cnt].index = freq_cnt;
+ freq_table[cpu][freq_cnt].frequency = CPUFREQ_TABLE_END;
+ /* Register table with CPUFreq. */
+ cpufreq_frequency_table_get_attr(freq_table[cpu], cpu);
+ pr_info("CPU%d: %d scaling frequencies supported.\n",
+ cpu, freq_cnt);
}
-
- /* freq_table not big enough to store all usable freqs. */
- BUG_ON(acpu_freq_tbl[i].a11clk_khz != 0);
-
- freq_table[freq_cnt].index = freq_cnt;
- freq_table[freq_cnt].frequency = CPUFREQ_TABLE_END;
-
- pr_info("%d scaling frequencies supported.\n", freq_cnt);
}
#endif
@@ -995,7 +1000,6 @@
#ifdef CONFIG_CPU_FREQ_MSM
cpufreq_table_init();
- cpufreq_frequency_table_get_attr(freq_table, smp_processor_id());
#endif
return 0;
}
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 57f4a0a..de80a3e 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -21,6 +21,7 @@
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/gpiomux.h>
+#include <mach/socinfo.h>
#include "devices.h"
#include "board-8064.h"
@@ -34,17 +35,24 @@
/* The SPI configurations apply to GSBI 5*/
static struct gpiomux_setting gpio_spi_config = {
.func = GPIOMUX_FUNC_2,
- .drv = GPIOMUX_DRV_8MA,
+ .drv = GPIOMUX_DRV_12MA,
.pull = GPIOMUX_PULL_NONE,
};
/* The SPI configurations apply to GSBI 5 chip select 2*/
static struct gpiomux_setting gpio_spi_cs2_config = {
.func = GPIOMUX_FUNC_3,
- .drv = GPIOMUX_DRV_8MA,
+ .drv = GPIOMUX_DRV_12MA,
.pull = GPIOMUX_PULL_NONE,
};
+/* Chip selects for SPI clients */
+static struct gpiomux_setting gpio_spi_cs_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_12MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
struct msm_gpiomux_config apq8064_ethernet_configs[] = {
{
.gpio = 43,
@@ -89,6 +97,45 @@
.pull = GPIOMUX_PULL_NONE,
};
+static struct gpiomux_setting ext_regulator_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+ .dir = GPIOMUX_OUT_LOW,
+};
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct gpiomux_setting hsic_act_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting hsic_sus_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+ .dir = GPIOMUX_OUT_LOW,
+};
+
+static struct msm_gpiomux_config apq8064_hsic_configs[] = {
+ {
+ .gpio = 88, /*HSIC_STROBE */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hsic_act_cfg,
+ [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+ },
+ },
+ {
+ .gpio = 89, /* HSIC_DATA */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hsic_act_cfg,
+ [GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+ },
+ },
+};
+#endif
+
static struct msm_gpiomux_config apq8064_gsbi_configs[] __initdata = {
{
.gpio = 18, /* GSBI1 UART TX */
@@ -116,6 +163,12 @@
},
},
{
+ .gpio = 53, /* Funny CS0 */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_config,
+ },
+ },
+ {
.gpio = 31, /* GSBI5 QUP SPI_CS2_N */
.settings = {
[GPIOMUX_SUSPENDED] = &gpio_spi_cs2_config,
@@ -128,6 +181,24 @@
},
},
#endif
+ {
+ .gpio = 30, /* FP CS */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+ },
+ },
+ {
+ .gpio = 32, /* EPM CS */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+ },
+ },
+ {
+ .gpio = 53, /* NOR CS */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+ },
+ },
};
static struct msm_gpiomux_config apq8064_slimbus_config[] __initdata = {
@@ -185,6 +256,78 @@
},
};
+/* External 3.3 V regulator enable */
+static struct msm_gpiomux_config apq8064_ext_regulator_configs[] __initdata = {
+ {
+ .gpio = APQ8064_EXT_3P3V_REG_EN_GPIO,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ext_regulator_config,
+ },
+ },
+};
+
+static struct gpiomux_setting ap2mdm_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mdm2ap_status_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mdm2ap_errfatal_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_16MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting ap2mdm_pon_reset_n_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct msm_gpiomux_config mdm_configs[] __initdata = {
+ /* AP2MDM_STATUS */
+ {
+ .gpio = 48,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+ }
+ },
+ /* MDM2AP_STATUS */
+ {
+ .gpio = 49,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
+ }
+ },
+ /* MDM2AP_ERRFATAL */
+ {
+ .gpio = 19,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
+ }
+ },
+ /* AP2MDM_ERRFATAL */
+ {
+ .gpio = 18,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+ }
+ },
+ /* AP2MDM_PON_RESET_N */
+ {
+ .gpio = 27,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &ap2mdm_pon_reset_n_cfg,
+ }
+ }
+};
+
void __init apq8064_init_gpiomux(void)
{
int rc;
@@ -211,4 +354,16 @@
msm_gpiomux_install(apq8064_audio_auxpcm_configs,
ARRAY_SIZE(apq8064_audio_auxpcm_configs));
+
+ msm_gpiomux_install(apq8064_ext_regulator_configs,
+ ARRAY_SIZE(apq8064_ext_regulator_configs));
+
+ if (machine_is_apq8064_mtp())
+ msm_gpiomux_install(mdm_configs,
+ ARRAY_SIZE(mdm_configs));
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+ msm_gpiomux_install(apq8064_hsic_configs,
+ ARRAY_SIZE(apq8064_hsic_configs));
+#endif
}
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 2182079..5204e48 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,15 +15,236 @@
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/bootmem.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/leds.h>
+#include <linux/leds-pm8xxx.h>
+#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
#include <asm/mach-types.h>
#include <asm/mach/mmc.h>
#include <mach/msm_bus_board.h>
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/gpiomux.h>
+#include <mach/restart.h>
#include "devices.h"
#include "board-8064.h"
+struct pm8xxx_gpio_init {
+ unsigned gpio;
+ struct pm_gpio config;
+};
+
+struct pm8xxx_mpp_init {
+ unsigned mpp;
+ struct pm8xxx_mpp_config_data config;
+};
+
+#define PM8921_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
+ _func, _inv, _disable) \
+{ \
+ .gpio = PM8921_GPIO_PM_TO_SYS(_gpio), \
+ .config = { \
+ .direction = _dir, \
+ .output_buffer = _buf, \
+ .output_value = _val, \
+ .pull = _pull, \
+ .vin_sel = _vin, \
+ .out_strength = _out_strength, \
+ .function = _func, \
+ .inv_int_pol = _inv, \
+ .disable_pin = _disable, \
+ } \
+}
+
+#define PM8921_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+ .mpp = PM8921_MPP_PM_TO_SYS(_mpp), \
+ .config = { \
+ .type = PM8XXX_MPP_TYPE_##_type, \
+ .level = _level, \
+ .control = PM8XXX_MPP_##_control, \
+ } \
+}
+
+#define PM8821_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+ .mpp = PM8821_MPP_PM_TO_SYS(_mpp), \
+ .config = { \
+ .type = PM8XXX_MPP_TYPE_##_type, \
+ .level = _level, \
+ .control = PM8XXX_MPP_##_control, \
+ } \
+}
+
+#define PM8921_GPIO_DISABLE(_gpio) \
+ PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
+ 0, 0, 0, 1)
+
+#define PM8921_GPIO_OUTPUT(_gpio, _val, _strength) \
+ PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+ PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+ PM_GPIO_STRENGTH_##_strength, \
+ PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8921_GPIO_INPUT(_gpio, _pull) \
+ PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
+ _pull, PM_GPIO_VIN_S4, \
+ PM_GPIO_STRENGTH_NO, \
+ PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8921_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
+ PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+ PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+ PM_GPIO_STRENGTH_HIGH, \
+ _func, 0, 0)
+
+#define PM8921_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
+ PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+ PM_GPIO_PULL_NO, _vin, \
+ PM_GPIO_STRENGTH_HIGH, \
+ PM_GPIO_FUNC_NORMAL, 0, 0)
+
+/* Initial PM8921 GPIO configurations */
+static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
+};
+
+/* Initial PM8XXX MPP configurations */
+static struct pm8xxx_mpp_init pm8xxx_mpps[] __initdata = {
+ /* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
+ PM8921_MPP_INIT(7, D_INPUT, PM8921_MPP_DIG_LEVEL_VPH, DIN_TO_INT),
+};
+
+void __init apq8064_pm8xxx_gpio_mpp_init(void)
+{
+ int i, rc;
+
+ for (i = 0; i < ARRAY_SIZE(pm8921_gpios); i++) {
+ rc = pm8xxx_gpio_config(pm8921_gpios[i].gpio,
+ &pm8921_gpios[i].config);
+ if (rc) {
+ pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
+ break;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(pm8xxx_mpps); i++) {
+ rc = pm8xxx_mpp_config(pm8xxx_mpps[i].mpp,
+ &pm8xxx_mpps[i].config);
+ if (rc) {
+ pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
+ break;
+ }
+ }
+}
+
+static struct pm8xxx_pwrkey_platform_data apq8064_pm8921_pwrkey_pdata = {
+ .pull_up = 1,
+ .kpd_trigger_delay_us = 15625,
+ .wakeup = 1,
+};
+
+static struct pm8xxx_misc_platform_data apq8064_pm8921_misc_pdata = {
+ .priority = 0,
+};
+
+#define PM8921_LC_LED_MAX_CURRENT 4 /* I = 4mA */
+#define PM8921_LC_LED_LOW_CURRENT 1 /* I = 1mA */
+#define PM8XXX_LED_PWM_PERIOD 1000
+#define PM8XXX_LED_PWM_DUTY_MS 20
+/**
+ * PM8XXX_PWM_CHANNEL_NONE shall be used when LED shall not be
+ * driven using PWM feature.
+ */
+#define PM8XXX_PWM_CHANNEL_NONE -1
+
+static struct led_info pm8921_led_info[] = {
+ [0] = {
+ .name = "led:red",
+ .default_trigger = "ac-online",
+ },
+};
+
+static struct led_platform_data pm8921_led_core_pdata = {
+ .num_leds = ARRAY_SIZE(pm8921_led_info),
+ .leds = pm8921_led_info,
+};
+
+static int pm8921_led0_pwm_duty_pcts[56] = {
+ 1, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 46, 52, 56, 60, 64, 68, 72, 76,
+ 80, 84, 88, 92, 96, 100, 100, 100, 98, 95,
+ 92, 88, 84, 82, 78, 74, 70, 66, 62, 58,
+ 58, 54, 50, 48, 42, 38, 34, 30, 26, 22,
+ 14, 10, 6, 4, 1
+};
+
+static struct pm8xxx_pwm_duty_cycles pm8921_led0_pwm_duty_cycles = {
+ .duty_pcts = (int *)&pm8921_led0_pwm_duty_pcts,
+ .num_duty_pcts = ARRAY_SIZE(pm8921_led0_pwm_duty_pcts),
+ .duty_ms = PM8XXX_LED_PWM_DUTY_MS,
+ .start_idx = 0,
+};
+
+static struct pm8xxx_led_config pm8921_led_configs[] = {
+ [0] = {
+ .id = PM8XXX_ID_LED_0,
+ .mode = PM8XXX_LED_MODE_PWM2,
+ .max_current = PM8921_LC_LED_MAX_CURRENT,
+ .pwm_channel = 5,
+ .pwm_period_us = PM8XXX_LED_PWM_PERIOD,
+ .pwm_duty_cycles = &pm8921_led0_pwm_duty_cycles,
+ },
+};
+
+static struct pm8xxx_led_platform_data apq8064_pm8921_leds_pdata = {
+ .led_core = &pm8921_led_core_pdata,
+ .configs = pm8921_led_configs,
+ .num_configs = ARRAY_SIZE(pm8921_led_configs),
+};
+
+static struct pm8xxx_adc_amux apq8064_pm8921_adc_channels_data[] = {
+ {"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
+ {"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
+ {"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+ {"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
+ ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
+};
+
+static struct pm8xxx_adc_properties apq8064_pm8921_adc_data = {
+ .adc_vdd_reference = 1800, /* milli-voltage for this adc */
+ .bitresolution = 15,
+ .bipolar = 0,
+};
+
+static struct pm8xxx_adc_platform_data apq8064_pm8921_adc_pdata = {
+ .adc_channel = apq8064_pm8921_adc_channels_data,
+ .adc_num_board_channel = ARRAY_SIZE(apq8064_pm8921_adc_channels_data),
+ .adc_prop = &apq8064_pm8921_adc_data,
+ .adc_mpp_base = PM8921_MPP_PM_TO_SYS(1),
+};
static struct pm8xxx_mpp_platform_data
apq8064_pm8921_mpp_pdata __devinitdata = {
@@ -49,6 +270,48 @@
.rtc_alarm_powerup = false,
};
+static int apq8064_pm8921_therm_mitigation[] = {
+ 1100,
+ 700,
+ 600,
+ 325,
+};
+
+#define MAX_VOLTAGE_MV 4200
+static struct pm8921_charger_platform_data
+apq8064_pm8921_chg_pdata __devinitdata = {
+ .safety_time = 180,
+ .update_time = 60000,
+ .max_voltage = MAX_VOLTAGE_MV,
+ .min_voltage = 3200,
+ .resume_voltage_delta = 100,
+ .term_current = 100,
+ .cool_temp = 10,
+ .warm_temp = 40,
+ .temp_check_period = 1,
+ .max_bat_chg_current = 1100,
+ .cool_bat_chg_current = 350,
+ .warm_bat_chg_current = 350,
+ .cool_bat_voltage = 4100,
+ .warm_bat_voltage = 4100,
+ .thermal_mitigation = apq8064_pm8921_therm_mitigation,
+ .thermal_levels = ARRAY_SIZE(apq8064_pm8921_therm_mitigation),
+};
+
+static struct pm8xxx_ccadc_platform_data
+apq8064_pm8xxx_ccadc_pdata = {
+ .r_sense = 10,
+};
+
+static struct pm8921_bms_platform_data
+apq8064_pm8921_bms_pdata __devinitdata = {
+ .r_sense = 10,
+ .i_test = 2500,
+ .v_failure = 3000,
+ .calib_delay_ms = 600000,
+ .max_voltage_uv = MAX_VOLTAGE_MV * 1000,
+};
+
static struct pm8921_platform_data
apq8064_pm8921_platform_data __devinitdata = {
.regulator_pdatas = msm8064_pm8921_regulator_pdata,
@@ -56,12 +319,19 @@
.gpio_pdata = &apq8064_pm8921_gpio_pdata,
.mpp_pdata = &apq8064_pm8921_mpp_pdata,
.rtc_pdata = &apq8064_pm8921_rtc_pdata,
+ .pwrkey_pdata = &apq8064_pm8921_pwrkey_pdata,
+ .misc_pdata = &apq8064_pm8921_misc_pdata,
+ .leds_pdata = &apq8064_pm8921_leds_pdata,
+ .adc_pdata = &apq8064_pm8921_adc_pdata,
+ .charger_pdata = &apq8064_pm8921_chg_pdata,
+ .bms_pdata = &apq8064_pm8921_bms_pdata,
+ .ccadc_pdata = &apq8064_pm8xxx_ccadc_pdata,
};
static struct pm8xxx_irq_platform_data
apq8064_pm8821_irq_pdata __devinitdata = {
.irq_base = PM8821_IRQ_BASE,
- .devirq = PM8821_USR_IRQ_N,
+ .devirq = PM8821_SEC_IRQ_N,
.irq_trigger_flag = IRQF_TRIGGER_HIGH,
.dev_id = 1,
};
@@ -95,6 +365,8 @@
void __init apq8064_init_pmic(void)
{
+ pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
+
apq8064_device_ssbi_pmic1.dev.platform_data =
&apq8064_ssbi_pm8921_pdata;
apq8064_device_ssbi_pmic2.dev.platform_data =
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 7267f96..f3eebce 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -129,6 +129,7 @@
REGULATOR_SUPPLY("HSUSB_VDDCX", "msm_otg"),
REGULATOR_SUPPLY("HSUSB_VDDCX", "msm_ehci_host.0"),
REGULATOR_SUPPLY("HSUSB_VDDCX", "msm_ehci_host.1"),
+ REGULATOR_SUPPLY("HSIC_VDDCX", "msm_hsic_host"),
REGULATOR_SUPPLY("riva_vddcx", "wcnss_wlan.0"),
};
VREG_CONSUMERS(S4) = {
@@ -179,6 +180,7 @@
};
VREG_CONSUMERS(USB_OTG) = {
REGULATOR_SUPPLY("8921_usb_otg", NULL),
+ REGULATOR_SUPPLY("vbus_otg", "msm_otg"),
};
VREG_CONSUMERS(HDMI_MVS) = {
REGULATOR_SUPPLY("8921_hdmi_mvs", NULL),
@@ -194,6 +196,14 @@
REGULATOR_SUPPLY("8821_s1", NULL),
REGULATOR_SUPPLY("krait3", NULL),
};
+VREG_CONSUMERS(EXT_5V) = {
+ REGULATOR_SUPPLY("ext_5v", NULL),
+};
+VREG_CONSUMERS(EXT_3P3V) = {
+ REGULATOR_SUPPLY("ext_3p3v", NULL),
+ REGULATOR_SUPPLY("vdd_io", "spi0.2"),
+ REGULATOR_SUPPLY("mhl_ext_3p3v", "msm_otg"),
+};
#define PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \
_apply_uV, _pull_down, _always_on, _supply_regulator, \
@@ -290,6 +300,22 @@
.pin_ctrl = _pin_ctrl, \
}
+#define GPIO_VREG(_id, _reg_name, _gpio_label, _gpio, _supply_regulator) \
+ [GPIO_VREG_ID_##_id] = { \
+ .init_data = { \
+ .constraints = { \
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS, \
+ }, \
+ .num_consumer_supplies = \
+ ARRAY_SIZE(vreg_consumers_##_id), \
+ .consumer_supplies = vreg_consumers_##_id, \
+ .supply_regulator = _supply_regulator, \
+ }, \
+ .regulator_name = _reg_name, \
+ .gpio_label = _gpio_label, \
+ .gpio = _gpio, \
+ }
+
#define SAW_VREG_INIT(_id, _name, _min_uV, _max_uV) \
{ \
.constraints = { \
@@ -302,6 +328,15 @@
.consumer_supplies = vreg_consumers_##_id, \
}
+/* GPIO regulator constraints */
+struct gpio_regulator_platform_data
+apq8064_gpio_regulator_pdata[] __devinitdata = {
+ /* ID vreg_name gpio_label gpio supply */
+ GPIO_VREG(EXT_5V, "ext_5v", "ext_5v_en", PM8921_MPP_PM_TO_SYS(7), NULL),
+ GPIO_VREG(EXT_3P3V, "ext_3p3v", "ext_3p3v_en",
+ APQ8064_EXT_3P3V_REG_EN_GPIO, NULL),
+};
+
/* SAW regulator constraints */
struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5 =
/* ID vreg_name min_uV max_uV */
@@ -329,7 +364,7 @@
3),
PM8XXX_SMPS(S4, "8921_s4", 1, 1, 1800000, 1800000, 500, NULL, 100000,
4),
- PM8XXX_SMPS(S7, "8921_s7", 0, 1, 1200000, 1200000, 500, NULL, 100000,
+ PM8XXX_SMPS(S7, "8921_s7", 0, 1, 1300000, 1300000, 500, NULL, 100000,
5),
PM8XXX_LDO(L1, "8921_l1", 1, 1, 1100000, 1100000, 200, "8921_s4", 0,
@@ -337,10 +372,11 @@
PM8XXX_LDO(L2, "8921_l2", 0, 1, 1200000, 1200000, 200, "8921_s4", 0,
7),
PM8XXX_LDO(L3, "8921_l3", 0, 1, 3075000, 3075000, 200, NULL, 0, 8),
- PM8XXX_LDO(L4, "8921_l4", 1, 1, 1800000, 1800000, 200, NULL, 0, 9),
+ PM8XXX_LDO(L4, "8921_l4", 1, 1, 1800000, 1800000, 200, NULL, 10000,
+ 9),
PM8XXX_LDO(L5, "8921_l5", 0, 1, 2950000, 2950000, 200, NULL, 0, 10),
PM8XXX_LDO(L6, "8921_l6", 0, 1, 2950000, 2950000, 200, NULL, 0, 11),
- PM8XXX_LDO(L7, "8921_l7", 1, 1, 1850000, 2950000, 200, NULL, 0, 12),
+ PM8XXX_LDO(L7, "8921_l7", 0, 1, 1850000, 2950000, 200, NULL, 0, 12),
PM8XXX_LDO(L8, "8921_l8", 0, 1, 2800000, 2800000, 200, NULL, 0, 13),
PM8XXX_LDO(L9, "8921_l9", 0, 1, 2850000, 2850000, 200, NULL, 0, 14),
PM8XXX_LDO(L10, "8921_l10", 0, 1, 2900000, 2900000, 200, NULL, 0, 15),
@@ -358,10 +394,10 @@
PM8XXX_NLDO1200(L24, "8921_l24", 1, 1, 1150000, 1150000, 200, "8921_s1",
10000, 25),
PM8XXX_NLDO1200(L25, "8921_l25", 1, 1, 1225000, 1225000, 200, "8921_s1",
- 0, 26),
+ 10000, 26),
PM8XXX_NLDO1200(L26, "8921_l26", 0, 1, 1050000, 1050000, 200, "8921_s7",
0, 27),
- PM8XXX_NLDO1200(L27, "8921_l27", 0, 1, 1000000, 1000000, 200, "8921_s7",
+ PM8XXX_NLDO1200(L27, "8921_l27", 0, 1, 1100000, 1100000, 200, "8921_s7",
0, 28),
PM8XXX_NLDO1200(L28, "8921_l28", 0, 1, 1050000, 1050000, 200, "8921_s7",
0, 29),
@@ -375,8 +411,8 @@
PM8XXX_VS(LVS6, "8921_lvs6", 0, 1, 0, "8921_s4", 35),
PM8XXX_VS(LVS7, "8921_lvs7", 1, 1, 0, "8921_s4", 36),
- PM8XXX_VS300(USB_OTG, "8921_usb_otg", 0, 1, 0, NULL, 37),
- PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1, 0, NULL, 38),
+ PM8XXX_VS300(USB_OTG, "8921_usb_otg", 0, 0, 0, "ext_5v", 37),
+ PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1, 0, "ext_5v", 38),
/* ID name always_on min_uV max_uV en_t supply reg_ID */
PM8XXX_NCP(NCP, "8921_ncp", 0, 1800000, 1800000, 200, "8921_l6", 39),
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index a95d733..febc55d 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -50,6 +50,7 @@
#include <mach/dma.h>
#include <mach/msm_bus_board.h>
#include <mach/cpuidle.h>
+#include <mach/mdm2.h>
#include "msm_watchdog.h"
#include "board-8064.h"
@@ -374,15 +375,85 @@
msm_reserve();
}
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct msm_hsic_host_platform_data msm_hsic_pdata = {
+ .strobe = 88,
+ .data = 89,
+};
+#else
+static struct msm_hsic_host_platform_data msm_hsic_pdata;
+#endif
+
+#define PID_MAGIC_ID 0x71432909
+#define SERIAL_NUM_MAGIC_ID 0x61945374
+#define SERIAL_NUMBER_LENGTH 127
+#define DLOAD_USB_BASE_ADD 0x2A03F0C8
+
+struct magic_num_struct {
+ uint32_t pid;
+ uint32_t serial_num;
+};
+
+struct dload_struct {
+ uint32_t reserved1;
+ uint32_t reserved2;
+ uint32_t reserved3;
+ uint16_t reserved4;
+ uint16_t pid;
+ char serial_number[SERIAL_NUMBER_LENGTH];
+ uint16_t reserved5;
+ struct magic_num_struct magic_struct;
+};
+
+static int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum)
+{
+ struct dload_struct __iomem *dload = 0;
+
+ dload = ioremap(DLOAD_USB_BASE_ADD, sizeof(*dload));
+ if (!dload) {
+ pr_err("%s: cannot remap I/O memory region: %08x\n",
+ __func__, DLOAD_USB_BASE_ADD);
+ return -ENXIO;
+ }
+
+ pr_debug("%s: dload:%p pid:%x serial_num:%s\n",
+ __func__, dload, pid, snum);
+ /* update pid */
+ dload->magic_struct.pid = PID_MAGIC_ID;
+ dload->pid = pid;
+
+ /* update serial number */
+ dload->magic_struct.serial_num = 0;
+ if (!snum) {
+ memset(dload->serial_number, 0, SERIAL_NUMBER_LENGTH);
+ goto out;
+ }
+
+ dload->magic_struct.serial_num = SERIAL_NUM_MAGIC_ID;
+ strlcpy(dload->serial_number, snum, SERIAL_NUMBER_LENGTH);
+out:
+ iounmap(dload);
+ return 0;
+}
+
+static struct android_usb_platform_data android_usb_pdata = {
+ .update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
+};
+
static struct platform_device android_usb_device = {
- .name = "android_usb",
- .id = -1,
+ .name = "android_usb",
+ .id = -1,
+ .dev = {
+ .platform_data = &android_usb_pdata,
+ },
};
static struct msm_otg_platform_data msm_otg_pdata = {
- .mode = USB_PERIPHERAL,
- .otg_control = OTG_PHY_CONTROL,
+ .mode = USB_OTG,
+ .otg_control = OTG_PMIC_CONTROL,
.phy_type = SNPS_28NM_INTEGRATED_PHY,
+ .pmic_id_irq = PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
+ .power_budget = 750,
};
#define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS + NR_PM8921_IRQS)
@@ -567,6 +638,11 @@
};
#endif
+static struct mdm_platform_data mdm_platform_data = {
+ .mdm_version = "3.0",
+ .ramdump_delay_ms = 2000,
+ .peripheral_platform_device = &apq8064_device_hsic_host,
+};
#define MSM_SHARED_RAM_PHYS 0x80000000
static void __init apq8064_map_io(void)
@@ -1006,16 +1082,38 @@
msm_bus_8064_cpss_fpb.dev.platform_data = &msm_bus_8064_cpss_fpb_pdata;
}
+static struct platform_device apq8064_device_ext_5v_vreg __devinitdata = {
+ .name = GPIO_REGULATOR_DEV_NAME,
+ .id = PM8921_MPP_PM_TO_SYS(7),
+ .dev = {
+ .platform_data
+ = &apq8064_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V],
+ },
+};
+
+static struct platform_device apq8064_device_ext_3p3v_vreg __devinitdata = {
+ .name = GPIO_REGULATOR_DEV_NAME,
+ .id = APQ8064_EXT_3P3V_REG_EN_GPIO,
+ .dev = {
+ .platform_data =
+ &apq8064_gpio_regulator_pdata[GPIO_VREG_ID_EXT_3P3V],
+ },
+};
+
static struct platform_device *common_devices[] __initdata = {
&apq8064_device_dmov,
&apq8064_device_qup_i2c_gsbi4,
&apq8064_device_qup_spi_gsbi5,
&apq8064_slim_ctrl,
+ &apq8064_device_ext_5v_vreg,
+ &apq8064_device_ext_3p3v_vreg,
&apq8064_device_ssbi_pmic1,
&apq8064_device_ssbi_pmic2,
&msm_device_smd_apq8064,
&apq8064_device_otg,
&apq8064_device_gadget_peripheral,
+ &apq8064_device_hsusb_host,
+ &apq8064_device_hsic_host,
&android_usb_device,
#ifdef CONFIG_ANDROID_PMEM
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -1078,6 +1176,7 @@
&msm_device_vidc,
&msm_8960_riva,
&msm_8960_q6_lpass,
+ &msm_gss,
};
static struct platform_device *sim_devices[] __initdata = {
@@ -1099,7 +1198,7 @@
};
static struct msm_spi_platform_data apq8064_qup_spi_gsbi5_pdata = {
- .max_clock_speed = 24000000,
+ .max_clock_speed = 1100000,
};
#define KS8851_IRQ_GPIO 43
@@ -1138,7 +1237,7 @@
&apq8064_i2c_qup_gsbi4_pdata;
}
-#ifdef CONFIG_KS8851
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
static int ethernet_init(void)
{
int ret;
@@ -1180,9 +1279,13 @@
apq8064_device_qup_spi_gsbi5.dev.platform_data =
&apq8064_qup_spi_gsbi5_pdata;
apq8064_init_pmic();
+ if (machine_is_apq8064_liquid())
+ msm_otg_pdata.mhl_enable = true;
apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
+ apq8064_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
apq8064_init_buses();
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+ apq8064_pm8xxx_gpio_mpp_init();
apq8064_init_mmc();
slim_register_board_info(apq8064_slim_devices,
ARRAY_SIZE(apq8064_slim_devices));
@@ -1195,6 +1298,10 @@
msm_pm_data);
BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+ if (machine_is_apq8064_mtp()) {
+ mdm_8064_device.dev.platform_data = &mdm_platform_data;
+ platform_device_register(&mdm_8064_device);
+ }
}
static void __init apq8064_allocate_memory_regions(void)
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 4735504..e1451f5 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -13,9 +13,12 @@
#ifndef __ARCH_ARM_MACH_MSM_BOARD_APQ8064_H
#define __ARCH_ARM_MACH_MSM_BOARD_APQ8064_H
+#include <linux/regulator/gpio-regulator.h>
#include <linux/mfd/pm8xxx/pm8921.h>
#include <linux/mfd/pm8xxx/pm8821.h>
#include <mach/msm_memtypes.h>
+#include <mach/irqs.h>
+
/* Macros assume PMIC GPIOs and MPPs start at 1 */
#define PM8921_GPIO_BASE NR_GPIO_IRQS
#define PM8921_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio - 1 + PM8921_GPIO_BASE)
@@ -32,6 +35,14 @@
extern int msm8064_pm8921_regulator_pdata_len __devinitdata;
+#define GPIO_VREG_ID_EXT_5V 0
+#define GPIO_VREG_ID_EXT_3P3V 1
+
+#define APQ8064_EXT_3P3V_REG_EN_GPIO 77
+
+extern struct gpio_regulator_platform_data
+ apq8064_gpio_regulator_pdata[] __devinitdata;
+
extern struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5;
extern struct regulator_init_data msm8064_saw_regulator_pdata_8921_s6;
extern struct regulator_init_data msm8064_saw_regulator_pdata_8821_s0;
@@ -54,5 +65,6 @@
void apq8064_mdp_writeback(struct memtype_reserve *reserve_table);
void apq8064_init_gpu(void);
+void apq8064_pm8xxx_gpio_mpp_init(void);
#endif
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 2394019..47e51a3 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4840,6 +4840,7 @@
CLK_LOOKUP("xo", pxo_clk.c, "pil_qdsp6v4.0"),
CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.1"),
CLK_LOOKUP("xo", cxo_clk.c, "pil_qdsp6v4.2"),
+ CLK_LOOKUP("xo", cxo_clk.c, "pil_gss"),
CLK_LOOKUP("pll2", pll2_clk.c, NULL),
CLK_LOOKUP("pll8", pll8_clk.c, NULL),
CLK_LOOKUP("pll4", pll4_clk.c, NULL),
@@ -4867,7 +4868,7 @@
CLK_LOOKUP("core_clk", gp0_clk.c, ""),
CLK_LOOKUP("core_clk", gp1_clk.c, ""),
CLK_LOOKUP("core_clk", gp2_clk.c, ""),
- CLK_LOOKUP("core_clk", gsbi1_uart_clk.c, ""),
+ CLK_LOOKUP("core_clk", gsbi1_uart_clk.c, "msm_serial_hsl.0"),
CLK_LOOKUP("core_clk", gsbi2_uart_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi3_uart_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi4_uart_clk.c, ""),
@@ -4878,11 +4879,11 @@
CLK_LOOKUP("core_clk", gsbi2_qup_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi3_qup_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi4_qup_clk.c, ""),
- CLK_LOOKUP("core_clk", gsbi5_qup_clk.c, ""),
+ CLK_LOOKUP("core_clk", gsbi5_qup_clk.c, "spi_qsd.0"),
CLK_LOOKUP("core_clk", gsbi6_qup_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi7_qup_clk.c, ""),
CLK_LOOKUP("core_clk", pdm_clk.c, ""),
- CLK_LOOKUP("pmem_clk", pmem_clk.c, NULL),
+ CLK_LOOKUP("mem_clk", pmem_clk.c, "msm_sps"),
CLK_DUMMY("core_clk", PRNG_CLK, "msm_rng.0", OFF),
CLK_LOOKUP("core_clk", sdc1_clk.c, "msm_sdcc.1"),
CLK_LOOKUP("core_clk", sdc2_clk.c, "msm_sdcc.2"),
@@ -4907,11 +4908,11 @@
CLK_LOOKUP("ce3_core_src_clk", ce3_src_clk.c, "qce.0"),
CLK_LOOKUP("ce3_core_src_clk", ce3_src_clk.c, "qcrypto.0"),
CLK_LOOKUP("dma_bam_pclk", dma_bam_p_clk.c, NULL),
- CLK_LOOKUP("iface_clk", gsbi1_p_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gsbi1_p_clk.c, "msm_serial_hsl.0"),
CLK_LOOKUP("iface_clk", gsbi2_p_clk.c, ""),
CLK_LOOKUP("iface_clk", gsbi3_p_clk.c, ""),
CLK_LOOKUP("iface_clk", gsbi4_p_clk.c, ""),
- CLK_LOOKUP("iface_clk", gsbi5_p_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gsbi5_p_clk.c, "spi_qsd.0"),
CLK_LOOKUP("iface_clk", gsbi6_p_clk.c, ""),
CLK_LOOKUP("iface_clk", gsbi7_p_clk.c, ""),
CLK_LOOKUP("iface_clk", tsif_p_clk.c, ""),
@@ -5020,7 +5021,7 @@
CLK_LOOKUP("mem_iface_clk", imem_p_clk.c, "kgsl-3d0.0"),
CLK_LOOKUP("mdp_pclk", mdp_p_clk.c, ""),
CLK_LOOKUP("iface_clk", mdp_p_clk.c, "footswitch-8x60.4"),
- CLK_LOOKUP("iface_clk", smmu_p_clk.c, ""),
+ CLK_LOOKUP("iface_clk", smmu_p_clk.c, "msm_iommu"),
CLK_LOOKUP("iface_clk", rot_p_clk.c, "msm_rotator.0"),
CLK_LOOKUP("iface_clk", rot_p_clk.c, "footswitch-8x60.6"),
CLK_LOOKUP("iface_clk", vcodec_p_clk.c, "msm_vidc.0"),
@@ -5041,7 +5042,7 @@
CLK_LOOKUP("i2s_spkr_osr_clk", spare_i2s_spkr_osr_clk.c, ""),
CLK_LOOKUP("pcm_clk", pcm_clk.c, ""),
CLK_LOOKUP("sps_slimbus_clk", sps_slimbus_clk.c, ""),
- CLK_LOOKUP("audio_slimbus_clk", audio_slimbus_clk.c, ""),
+ CLK_LOOKUP("audio_slimbus_clk", audio_slimbus_clk.c, NULL),
CLK_LOOKUP("core_clk", jpegd_axi_clk.c, ""),
CLK_LOOKUP("core_clk", vpe_axi_clk.c, ""),
CLK_LOOKUP("core_clk", mdp_axi_clk.c, ""),
@@ -5068,6 +5069,19 @@
CLK_LOOKUP("core_clk", usb_hsic_system_clk.c, "msm_hsic_host"),
CLK_LOOKUP("iface_clk", usb_hsic_p_clk.c, "msm_hsic_host"),
+ CLK_LOOKUP("core_clk", jpegd_axi_clk.c, "msm_iommu.0"),
+ CLK_LOOKUP("core_clk", vpe_axi_clk.c, "msm_iommu.1"),
+ CLK_LOOKUP("core_clk", mdp_axi_clk.c, "msm_iommu.2"),
+ CLK_LOOKUP("core_clk", mdp_axi_clk.c, "msm_iommu.3"),
+ CLK_LOOKUP("core_clk", rot_axi_clk.c, "msm_iommu.4"),
+ CLK_LOOKUP("core_clk", ijpeg_axi_clk.c, "msm_iommu.5"),
+ CLK_LOOKUP("core_clk", vfe_axi_clk.c, "msm_iommu.6"),
+ CLK_LOOKUP("core_clk", vcodec_axi_a_clk.c, "msm_iommu.7"),
+ CLK_LOOKUP("core_clk", vcodec_axi_b_clk.c, "msm_iommu.8"),
+ CLK_LOOKUP("core_clk", gfx3d_axi_clk.c, "msm_iommu.9"),
+ CLK_LOOKUP("core_clk", gfx3d_axi_clk.c, "msm_iommu.10"),
+ CLK_LOOKUP("core_clk", vcap_axi_clk.c, "msm_iommu.11"),
+
CLK_LOOKUP("mem_clk", ebi1_adm_clk.c, "msm_dmov"),
CLK_LOOKUP("l2_mclk", l2_m_clk, ""),
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index f3ef2ce..faa9498 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/msm_rotator.h>
#include <linux/clkdev.h>
+#include <linux/dma-mapping.h>
#include <mach/irqs-8064.h>
#include <mach/board.h>
#include <mach/msm_iomap.h>
@@ -26,6 +27,7 @@
#include <sound/apr_audio.h>
#include <mach/msm_bus_board.h>
#include <mach/rpm.h>
+#include <mach/mdm2.h>
#include "clock.h"
#include "devices.h"
#include "msm_watchdog.h"
@@ -59,8 +61,8 @@
#define MSM_PMIC_SSBI_SIZE SZ_4K
/* Address of HS USBOTG1 */
-#define MSM_HSUSB_PHYS 0x12500000
-#define MSM_HSUSB_SIZE SZ_4K
+#define MSM_HSUSB1_PHYS 0x12500000
+#define MSM_HSUSB1_SIZE SZ_4K
static struct msm_watchdog_pdata msm_watchdog_pdata = {
.pet_time = 10000,
@@ -413,8 +415,8 @@
static struct resource resources_otg[] = {
{
- .start = MSM_HSUSB_PHYS,
- .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE - 1,
+ .start = MSM_HSUSB1_PHYS,
+ .end = MSM_HSUSB1_PHYS + MSM_HSUSB1_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
@@ -436,8 +438,8 @@
static struct resource resources_hsusb[] = {
{
- .start = MSM_HSUSB_PHYS,
- .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE - 1,
+ .start = MSM_HSUSB1_PHYS,
+ .end = MSM_HSUSB1_PHYS + MSM_HSUSB1_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
@@ -457,6 +459,61 @@
},
};
+static struct resource resources_hsusb_host[] = {
+ {
+ .start = MSM_HSUSB1_PHYS,
+ .end = MSM_HSUSB1_PHYS + MSM_HSUSB1_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = USB1_HS_IRQ,
+ .end = USB1_HS_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource resources_hsic_host[] = {
+ {
+ .start = 0x12510000,
+ .end = 0x12510000 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = USB2_HSIC_IRQ,
+ .end = USB2_HSIC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_GPIO_TO_INT(49),
+ .end = MSM_GPIO_TO_INT(49),
+ .name = "peripheral_status_irq",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 dma_mask = DMA_BIT_MASK(32);
+struct platform_device apq8064_device_hsusb_host = {
+ .name = "msm_hsusb_host",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsusb_host),
+ .resource = resources_hsusb_host,
+ .dev = {
+ .dma_mask = &dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device apq8064_device_hsic_host = {
+ .name = "msm_hsic_host",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsic_host),
+ .resource = resources_hsic_host,
+ .dev = {
+ .dma_mask = &dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
#define MSM_SDC1_BASE 0x12400000
#define MSM_SDC1_DML_BASE (MSM_SDC1_BASE + 0x800)
#define MSM_SDC1_BAM_BASE (MSM_SDC1_BASE + 0x2000)
@@ -754,6 +811,26 @@
};
#endif
+static struct resource msm_gss_resources[] = {
+ {
+ .start = 0x10000000,
+ .end = 0x10000000 + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x10008000,
+ .end = 0x10008000 + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device msm_gss = {
+ .name = "pil_gss",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(msm_gss_resources),
+ .resource = msm_gss_resources,
+};
+
static struct clk_lookup msm_clocks_8064_dummy[] = {
CLK_DUMMY("pll2", PLL2, NULL, 0),
CLK_DUMMY("pll8", PLL8, NULL, 0),
@@ -1329,3 +1406,50 @@
};
#endif
+
+#define MDM2AP_ERRFATAL 19
+#define AP2MDM_ERRFATAL 18
+#define MDM2AP_STATUS 49
+#define AP2MDM_STATUS 48
+#define AP2MDM_PMIC_RESET_N 27
+
+static struct resource mdm_resources[] = {
+ {
+ .start = MDM2AP_ERRFATAL,
+ .end = MDM2AP_ERRFATAL,
+ .name = "MDM2AP_ERRFATAL",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = AP2MDM_ERRFATAL,
+ .end = AP2MDM_ERRFATAL,
+ .name = "AP2MDM_ERRFATAL",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = MDM2AP_STATUS,
+ .end = MDM2AP_STATUS,
+ .name = "MDM2AP_STATUS",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = AP2MDM_STATUS,
+ .end = AP2MDM_STATUS,
+ .name = "AP2MDM_STATUS",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = AP2MDM_PMIC_RESET_N,
+ .end = AP2MDM_PMIC_RESET_N,
+ .name = "AP2MDM_PMIC_RESET_N",
+ .flags = IORESOURCE_IO,
+ },
+};
+
+struct platform_device mdm_8064_device = {
+ .name = "mdm2_modem",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mdm_resources),
+ .resource = mdm_resources,
+};
+
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 5d42f99..9469de8 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -102,6 +102,8 @@
extern struct platform_device apq8064_device_otg;
extern struct platform_device apq8064_usb_diag_device;
extern struct platform_device apq8064_device_gadget_peripheral;
+extern struct platform_device apq8064_device_hsusb_host;
+extern struct platform_device apq8064_device_hsic_host;
extern struct platform_device msm_device_i2c;
@@ -193,6 +195,7 @@
extern struct platform_device msm_8960_q6_mss_fw;
extern struct platform_device msm_8960_q6_mss_sw;
extern struct platform_device msm_8960_riva;
+extern struct platform_device msm_gss;
extern struct platform_device apq_pcm;
extern struct platform_device apq_pcm_routing;
@@ -292,3 +295,5 @@
extern struct platform_device msm_bus_8064_mm_fabric;
extern struct platform_device msm_bus_8064_sys_fpb;
extern struct platform_device msm_bus_8064_cpss_fpb;
+
+extern struct platform_device mdm_8064_device;
diff --git a/arch/arm/mach-msm/include/mach/irqs-8064.h b/arch/arm/mach-msm/include/mach/irqs-8064.h
index 8597111..a5f78f5 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8064.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8064.h
@@ -57,7 +57,7 @@
#define TLMM_MSM_DIR_CONN_IRQ_8 (GIC_SPI_START + 12)
#define TLMM_MSM_DIR_CONN_IRQ_9 (GIC_SPI_START + 13)
#define PM8921_SEC_IRQ_N (GIC_SPI_START + 14)
-#define PM8018_SEC_IRQ_N (GIC_SPI_START + 15)
+#define PM8821_SEC_IRQ_N (GIC_SPI_START + 15)
#define TLMM_MSM_SUMMARY_IRQ (GIC_SPI_START + 16)
#define SPDM_RT_1_IRQ (GIC_SPI_START + 17)
#define SPDM_DIAG_IRQ (GIC_SPI_START + 18)
diff --git a/arch/arm/mach-msm/include/mach/mdm2.h b/arch/arm/mach-msm/include/mach/mdm2.h
index acfa38a..78ca88f 100644
--- a/arch/arm/mach-msm/include/mach/mdm2.h
+++ b/arch/arm/mach-msm/include/mach/mdm2.h
@@ -15,6 +15,8 @@
struct mdm_platform_data {
char *mdm_version;
+ int ramdump_delay_ms;
+ struct platform_device *peripheral_platform_device;
};
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_rtb.h b/arch/arm/mach-msm/include/mach/msm_rtb.h
index 2831428..a24e892 100644
--- a/arch/arm/mach-msm/include/mach/msm_rtb.h
+++ b/arch/arm/mach-msm/include/mach/msm_rtb.h
@@ -32,6 +32,22 @@
*/
int uncached_logk(enum logk_event_type log_type, void *data);
+#define ETB_WAYPOINT do { \
+ BRANCH_TO_NEXT_ISTR; \
+ nop(); \
+ BRANCH_TO_NEXT_ISTR; \
+ nop(); \
+ } while (0)
+
+#define BRANCH_TO_NEXT_ISTR asm volatile("b .+4\n" : : : "memory")
+/*
+ * both the mb and the isb are needed to ensure enough waypoints for
+ * etb tracing
+ */
+#define LOG_BARRIER do { \
+ mb(); \
+ isb();\
+ } while (0)
#else
static inline int uncached_logk_pc(enum logk_event_type log_type,
@@ -40,5 +56,13 @@
static inline int uncached_logk(enum logk_event_type log_type,
void *data) { return 0; }
+
+#define ETB_WAYPOINT
+#define BRANCH_TO_NEXT_ISTR
+/*
+ * Due to a GCC bug, we need to have a nop here in order to prevent an extra
+ * read from being generated after the write.
+ */
+#define LOG_BARRIER nop()
#endif
#endif
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h b/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
index 68a3c44..d50fe2b 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -41,6 +41,7 @@
unsigned used; /* Input usage actual DSP produced PCM size */
unsigned addr;
};
+struct audio;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct audio_suspend_ctl {
diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h
index 7560dc2..d46bd77 100644
--- a/arch/arm/mach-msm/include/mach/uncompress.h
+++ b/arch/arm/mach-msm/include/mach/uncompress.h
@@ -1,6 +1,7 @@
/* arch/arm/mach-msm/include/mach/uncompress.h
*
* Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -34,18 +35,18 @@
* Wait for TX_READY to be set; but skip it if we have a
* TX underrun.
*/
- if (!(__raw_readl(base + UARTDM_SR_OFFSET) & 0x08))
- while (!(__raw_readl(base + UARTDM_ISR_OFFSET) & 0x80))
+ if (!(__raw_readl_no_log(base + UARTDM_SR_OFFSET) & 0x08))
+ while (!(__raw_readl_no_log(base + UARTDM_ISR_OFFSET) & 0x80))
cpu_relax();
- __raw_writel(0x300, base + UARTDM_CR_OFFSET);
- __raw_writel(0x1, base + UARTDM_NCF_TX_OFFSET);
- __raw_writel(c, base + UARTDM_TF_OFFSET);
+ __raw_writel_no_log(0x300, base + UARTDM_CR_OFFSET);
+ __raw_writel_no_log(0x1, base + UARTDM_NCF_TX_OFFSET);
+ __raw_writel_no_log(c, base + UARTDM_TF_OFFSET);
#else
/* Wait for TX_READY to be set */
- while (!(__raw_readl(base + 0x08) & 0x04))
+ while (!(__raw_readl_no_log(base + 0x08) & 0x04))
cpu_relax();
- __raw_writel(c, base + 0x0c);
+ __raw_writel_no_log(c, base + 0x0c);
#endif
#endif
}
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index bf4e6a4..5db8b40 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -33,7 +33,6 @@
#include <asm/mach-types.h>
#include <asm/uaccess.h>
#include <mach/mdm2.h>
-#include <mach/mdm-peripheral.h>
#include <mach/restart.h>
#include <mach/subsystem_notif.h>
#include <mach/subsystem_restart.h>
@@ -46,38 +45,63 @@
#define MDM_MODEM_TIMEOUT 6000
#define MDM_HOLD_TIME 4000
#define MDM_MODEM_DELTA 100
-#define IFLINE_UP 1
-#define IFLINE_DOWN 0
static int mdm_debug_on;
-static struct mdm_callbacks mdm_cb;
+static int first_power_on = 1;
+static int hsic_peripheral_status = 1;
+static DEFINE_MUTEX(hsic_status_lock);
-#define MDM_DBG(...) do { if (mdm_debug_on) \
- pr_info(__VA_ARGS__); \
- } while (0);
+static void mdm_peripheral_connect(struct mdm_modem_drv *mdm_drv)
+{
+ mutex_lock(&hsic_status_lock);
+ if (hsic_peripheral_status)
+ goto out;
+ if (mdm_drv->pdata->peripheral_platform_device)
+ platform_device_add(mdm_drv->pdata->peripheral_platform_device);
+ hsic_peripheral_status = 1;
+out:
+ mutex_unlock(&hsic_status_lock);
+}
+
+static void mdm_peripheral_disconnect(struct mdm_modem_drv *mdm_drv)
+{
+ mutex_lock(&hsic_status_lock);
+ if (!hsic_peripheral_status)
+ goto out;
+ if (mdm_drv->pdata->peripheral_platform_device)
+ platform_device_del(mdm_drv->pdata->peripheral_platform_device);
+ hsic_peripheral_status = 0;
+out:
+ mutex_unlock(&hsic_status_lock);
+}
static void power_on_mdm(struct mdm_modem_drv *mdm_drv)
{
- peripheral_disconnect();
+ mdm_peripheral_disconnect(mdm_drv);
- /* Pull both ERR_FATAL and RESET low */
- MDM_DBG("Pulling PWR and RESET gpio's low\n");
+ /* Pull RESET gpio low and wait for it to settle. */
+ pr_debug("Pulling RESET gpio low\n");
gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 0);
- gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 0);
- /* Wait for them to settle. */
usleep(1000);
/* Deassert RESET first and wait for ir to settle. */
- MDM_DBG("%s: Pulling RESET gpio high\n", __func__);
+ pr_debug("%s: Pulling RESET gpio high\n", __func__);
gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 1);
usleep(1000);
- /* Pull PWR gpio high and wait for it to settle. */
- MDM_DBG("%s: Powering on mdm modem\n", __func__);
- gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 1);
- usleep(1000);
-
- peripheral_connect();
+ /* Pull PWR gpio high and wait for it to settle, but only
+ * the first time the mdm is powered up.
+ * Some targets do not use ap2mdm_kpdpwr_n_gpio.
+ */
+ if (first_power_on) {
+ if (mdm_drv->ap2mdm_kpdpwr_n_gpio > 0) {
+ pr_debug("%s: Powering on mdm modem\n", __func__);
+ gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 1);
+ usleep(1000);
+ }
+ first_power_on = 0;
+ }
+ mdm_peripheral_connect(mdm_drv);
msleep(200);
}
@@ -92,7 +116,6 @@
if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
break;
}
-
if (i <= 0) {
pr_err("%s: MDM2AP_STATUS never went low.\n",
__func__);
@@ -103,12 +126,9 @@
msleep(MDM_MODEM_DELTA);
}
}
-
- peripheral_disconnect();
-}
-
-static void normal_boot_done(struct mdm_modem_drv *mdm_drv)
-{
+ if (mdm_drv->ap2mdm_kpdpwr_n_gpio > 0)
+ gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 0);
+ mdm_peripheral_disconnect(mdm_drv);
}
static void debug_state_changed(int value)
@@ -116,24 +136,25 @@
mdm_debug_on = value;
}
-static void mdm_status_changed(int value)
+static void mdm_status_changed(struct mdm_modem_drv *mdm_drv, int value)
{
- MDM_DBG("%s: value:%d\n", __func__, value);
+ pr_debug("%s: value:%d\n", __func__, value);
if (value) {
- peripheral_disconnect();
- peripheral_connect();
+ mdm_peripheral_disconnect(mdm_drv);
+ mdm_peripheral_connect(mdm_drv);
}
}
+static struct mdm_ops mdm_cb = {
+ .power_on_mdm_cb = power_on_mdm,
+ .power_down_mdm_cb = power_down_mdm,
+ .debug_state_changed_cb = debug_state_changed,
+ .status_cb = mdm_status_changed,
+};
+
static int __init mdm_modem_probe(struct platform_device *pdev)
{
- /* Instantiate driver object. */
- mdm_cb.power_on_mdm_cb = power_on_mdm;
- mdm_cb.power_down_mdm_cb = power_down_mdm;
- mdm_cb.normal_boot_done_cb = normal_boot_done;
- mdm_cb.debug_state_changed_cb = debug_state_changed;
- mdm_cb.status_cb = mdm_status_changed;
return mdm_common_create(pdev, &mdm_cb);
}
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 023df69..b672957 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -48,10 +48,6 @@
#define EXTERNAL_MODEM "external_modem"
-#define MDM_DBG(...) do { if (mdm_debug_on) \
- pr_info(__VA_ARGS__); \
- } while (0);
-
static struct mdm_modem_drv *mdm_drv;
DECLARE_COMPLETION(mdm_needs_reload);
@@ -70,11 +66,11 @@
return -EINVAL;
}
- MDM_DBG("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
+ pr_debug("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
switch (cmd) {
case WAKE_CHARM:
- MDM_DBG("%s: Powering on\n", __func__);
- mdm_drv->power_on_mdm_cb(mdm_drv);
+ pr_info("%s: Powering on mdm\n", __func__);
+ mdm_drv->ops->power_on_mdm_cb(mdm_drv);
break;
case CHECK_FOR_BOOT:
if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
@@ -83,16 +79,19 @@
put_user(0, (unsigned long __user *) arg);
break;
case NORMAL_BOOT_DONE:
- MDM_DBG("%s: check if mdm is booted up\n", __func__);
+ pr_debug("%s: check if mdm is booted up\n", __func__);
get_user(status, (unsigned long __user *) arg);
- if (status)
+ if (status) {
+ pr_debug("%s: normal boot failed\n", __func__);
mdm_drv->mdm_boot_status = -EIO;
- else
+ } else {
+ pr_info("%s: normal boot done\n", __func__);
mdm_drv->mdm_boot_status = 0;
+ }
mdm_drv->mdm_ready = 1;
- if (mdm_drv->normal_boot_done_cb != NULL)
- mdm_drv->normal_boot_done_cb(mdm_drv);
+ if (mdm_drv->ops->normal_boot_done_cb != NULL)
+ mdm_drv->ops->normal_boot_done_cb(mdm_drv);
if (!first_boot)
complete(&mdm_boot);
@@ -100,16 +99,18 @@
first_boot = 0;
break;
case RAM_DUMP_DONE:
- MDM_DBG("%s: mdm done collecting RAM dumps\n", __func__);
+ pr_debug("%s: mdm done collecting RAM dumps\n", __func__);
get_user(status, (unsigned long __user *) arg);
if (status)
mdm_drv->mdm_ram_dump_status = -EIO;
- else
+ else {
+ pr_info("%s: ramdump collection completed\n", __func__);
mdm_drv->mdm_ram_dump_status = 0;
+ }
complete(&mdm_ram_dumps);
break;
case WAIT_FOR_RESTART:
- MDM_DBG("%s: wait for mdm to need images reloaded\n",
+ pr_debug("%s: wait for mdm to need images reloaded\n",
__func__);
ret = wait_for_completion_interruptible(&mdm_needs_reload);
if (!ret)
@@ -128,7 +129,7 @@
static void mdm_fatal_fn(struct work_struct *work)
{
- MDM_DBG("%s: Reseting the mdm due to an errfatal\n", __func__);
+ pr_info("%s: Reseting the mdm due to an errfatal\n", __func__);
subsystem_restart(EXTERNAL_MODEM);
}
@@ -138,15 +139,15 @@
{
int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);
- mdm_drv->status_cb(value);
+ mdm_drv->ops->status_cb(mdm_drv, value);
- MDM_DBG("%s: status:%d\n", __func__, value);
+ pr_debug("%s: status:%d\n", __func__, value);
if ((value == 0) && mdm_drv->mdm_ready) {
- MDM_DBG("%s: scheduling work now\n", __func__);
+ pr_info("%s: unexpected reset external modem\n", __func__);
subsystem_restart(EXTERNAL_MODEM);
} else if (value == 1) {
- MDM_DBG("%s: mdm is now ready\n", __func__);
+ pr_info("%s: status = 1: mdm is now ready\n", __func__);
}
}
@@ -161,10 +162,10 @@
static irqreturn_t mdm_errfatal(int irq, void *dev_id)
{
- MDM_DBG("%s: mdm got errfatal interrupt\n", __func__);
+ pr_debug("%s: mdm got errfatal interrupt\n", __func__);
if (mdm_drv->mdm_ready &&
(gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 1)) {
- MDM_DBG("%s: scheduling work now\n", __func__);
+ pr_debug("%s: scheduling work now\n", __func__);
queue_work(mdm_queue, &mdm_fatal_work);
}
return IRQ_HANDLED;
@@ -193,7 +194,7 @@
{
int i;
- MDM_DBG("%s: setting AP2MDM_ERRFATAL high for a non graceful reset\n",
+ pr_debug("%s: setting AP2MDM_ERRFATAL high for a non graceful reset\n",
__func__);
mdm_disable_irqs();
gpio_set_value(mdm_drv->ap2mdm_errfatal_gpio, 1);
@@ -218,7 +219,7 @@
static irqreturn_t mdm_status_change(int irq, void *dev_id)
{
- MDM_DBG("%s: mdm sent status change interrupt\n", __func__);
+ pr_debug("%s: mdm sent status change interrupt\n", __func__);
queue_work(mdm_queue, &mdm_status_work);
@@ -229,13 +230,19 @@
{
mdm_drv->mdm_ready = 0;
gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 1);
- mdm_drv->power_down_mdm_cb(mdm_drv);
+ if (mdm_drv->pdata->ramdump_delay_ms > 0) {
+ /* Wait for the external modem to complete
+ * its preparation for ramdumps.
+ */
+ mdelay(mdm_drv->pdata->ramdump_delay_ms);
+ }
+ mdm_drv->ops->power_down_mdm_cb(mdm_drv);
return 0;
}
static int mdm_subsys_powerup(const struct subsys_data *crashed_subsys)
{
- mdm_drv->power_on_mdm_cb(mdm_drv);
+ mdm_drv->ops->power_on_mdm_cb(mdm_drv);
mdm_drv->boot_type = CHARM_NORMAL_BOOT;
complete(&mdm_needs_reload);
wait_for_completion(&mdm_boot);
@@ -254,7 +261,7 @@
wait_for_completion(&mdm_ram_dumps);
INIT_COMPLETION(mdm_ram_dumps);
gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 1);
- mdm_drv->power_down_mdm_cb(mdm_drv);
+ mdm_drv->ops->power_down_mdm_cb(mdm_drv);
}
return mdm_drv->mdm_ram_dump_status;
}
@@ -269,8 +276,8 @@
static int mdm_debug_on_set(void *data, u64 val)
{
mdm_debug_on = val;
- if (mdm_drv->debug_state_changed_cb)
- mdm_drv->debug_state_changed_cb(mdm_debug_on);
+ if (mdm_drv->ops->debug_state_changed_cb)
+ mdm_drv->ops->debug_state_changed_cb(mdm_debug_on);
return 0;
}
@@ -298,7 +305,7 @@
}
static void mdm_modem_initialize_data(struct platform_device *pdev,
- struct mdm_callbacks *p_mdm_cb)
+ struct mdm_ops *mdm_ops)
{
struct resource *pres;
@@ -352,15 +359,12 @@
mdm_drv->boot_type = CHARM_NORMAL_BOOT;
- mdm_drv->power_on_mdm_cb = p_mdm_cb->power_on_mdm_cb;
- mdm_drv->power_down_mdm_cb = p_mdm_cb->power_down_mdm_cb;
- mdm_drv->normal_boot_done_cb = p_mdm_cb->normal_boot_done_cb;
- mdm_drv->debug_state_changed_cb = p_mdm_cb->debug_state_changed_cb;
- mdm_drv->status_cb = p_mdm_cb->status_cb;
+ mdm_drv->ops = mdm_ops;
+ mdm_drv->pdata = pdev->dev.platform_data;
}
int mdm_common_create(struct platform_device *pdev,
- struct mdm_callbacks *p_mdm_cb)
+ struct mdm_ops *p_mdm_cb)
{
int ret = -1, irq;
@@ -371,8 +375,8 @@
}
mdm_modem_initialize_data(pdev, p_mdm_cb);
- if (mdm_drv->debug_state_changed_cb)
- mdm_drv->debug_state_changed_cb(mdm_debug_on);
+ if (mdm_drv->ops->debug_state_changed_cb)
+ mdm_drv->ops->debug_state_changed_cb(mdm_debug_on);
gpio_request(mdm_drv->ap2mdm_status_gpio, "AP2MDM_STATUS");
gpio_request(mdm_drv->ap2mdm_errfatal_gpio, "AP2MDM_ERRFATAL");
@@ -494,7 +498,7 @@
void mdm_common_modem_shutdown(struct platform_device *pdev)
{
- MDM_DBG("%s: setting AP2MDM_STATUS low for a graceful restart\n",
+ pr_debug("%s: setting AP2MDM_STATUS low for a graceful restart\n",
__func__);
mdm_disable_irqs();
@@ -504,7 +508,7 @@
if (mdm_drv->ap2mdm_wakeup_gpio > 0)
gpio_set_value(mdm_drv->ap2mdm_wakeup_gpio, 1);
- mdm_drv->power_down_mdm_cb(mdm_drv);
+ mdm_drv->ops->power_down_mdm_cb(mdm_drv);
if (mdm_drv->ap2mdm_wakeup_gpio > 0)
gpio_set_value(mdm_drv->ap2mdm_wakeup_gpio, 0);
diff --git a/arch/arm/mach-msm/mdm_private.h b/arch/arm/mach-msm/mdm_private.h
index bc8541e..206bd8b 100644
--- a/arch/arm/mach-msm/mdm_private.h
+++ b/arch/arm/mach-msm/mdm_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,6 +15,14 @@
struct mdm_modem_drv;
+struct mdm_ops {
+ void (*power_on_mdm_cb)(struct mdm_modem_drv *mdm_drv);
+ void (*normal_boot_done_cb)(struct mdm_modem_drv *mdm_drv);
+ void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
+ void (*debug_state_changed_cb)(int value);
+ void (*status_cb)(struct mdm_modem_drv *mdm_drv, int value);
+};
+
/* Private mdm2 data structure */
struct mdm_modem_drv {
unsigned mdm2ap_errfatal_gpio;
@@ -34,23 +42,12 @@
enum charm_boot_type boot_type;
int mdm_debug_on;
- void (*power_on_mdm_cb)(struct mdm_modem_drv *mdm_drv);
- void (*normal_boot_done_cb)(struct mdm_modem_drv *mdm_drv);
- void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
- void (*debug_state_changed_cb)(int value);
- void (*status_cb)(int value);
-};
-
-struct mdm_callbacks {
- void (*power_on_mdm_cb)(struct mdm_modem_drv *mdm_drv);
- void (*normal_boot_done_cb)(struct mdm_modem_drv *mdm_drv);
- void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
- void (*debug_state_changed_cb)(int value);
- void (*status_cb)(int value);
+ struct mdm_ops *ops;
+ struct mdm_platform_data *pdata;
};
int mdm_common_create(struct platform_device *pdev,
- struct mdm_callbacks *mdm_cb);
+ struct mdm_ops *mdm_cb);
int mdm_common_modem_remove(struct platform_device *pdev);
void mdm_common_modem_shutdown(struct platform_device *pdev);
void mdm_common_set_debug_state(int value);
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
new file mode 100644
index 0000000..f3e83d9
--- /dev/null
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/elf.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/clk.h>
+#include <linux/smp.h>
+
+#include <mach/msm_iomap.h>
+#include <mach/msm_xo.h>
+
+#include "peripheral-loader.h"
+#include "scm-pas.h"
+
+#define GSS_CSR_AHB_CLK_SEL 0x0
+#define GSS_CSR_RESET 0x4
+#define GSS_CSR_CLK_BLK_CONFIG 0x8
+#define GSS_CSR_CLK_ENABLE 0xC
+#define GSS_CSR_BOOT_REMAP 0x14
+#define GSS_CSR_POWER_UP_DOWN 0x18
+#define GSS_CSR_CFG_HID 0x2C
+
+#define GSS_SLP_CLK_CTL (MSM_CLK_CTL_BASE + 0x2C60)
+#define GSS_RESET (MSM_CLK_CTL_BASE + 0x2C64)
+#define GSS_CLAMP_ENA (MSM_CLK_CTL_BASE + 0x2C68)
+#define GSS_CXO_SRC_CTL (MSM_CLK_CTL_BASE + 0x2C74)
+
+#define PLL5_MODE (MSM_CLK_CTL_BASE + 0x30E0)
+#define PLL5_L_VAL (MSM_CLK_CTL_BASE + 0x30E4)
+#define PLL5_M_VAL (MSM_CLK_CTL_BASE + 0x30E8)
+#define PLL5_N_VAL (MSM_CLK_CTL_BASE + 0x30EC)
+#define PLL5_CONFIG (MSM_CLK_CTL_BASE + 0x30F4)
+#define PLL5_STATUS (MSM_CLK_CTL_BASE + 0x30F8)
+#define PLL_ENA_GSS (MSM_CLK_CTL_BASE + 0x3480)
+#define PLL_ENA_RPM (MSM_CLK_CTL_BASE + 0x34A0)
+
+#define PLL5_VOTE BIT(5)
+#define PLL_STATUS BIT(16)
+#define REMAP_ENABLE BIT(16)
+#define A5_POWER_STATUS BIT(4)
+#define A5_POWER_ENA BIT(0)
+#define NAV_POWER_ENA BIT(1)
+#define XO_CLK_BRANCH_ENA BIT(0)
+#define SLP_CLK_BRANCH_ENA BIT(4)
+#define A5_RESET BIT(0)
+
+#define PROXY_VOTE_TIMEOUT 10000
+
+struct gss_data {
+ void __iomem *base;
+ void __iomem *qgic2_base;
+ unsigned long start_addr;
+ struct delayed_work work;
+ struct clk *xo;
+};
+
+static int nop_verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
+{
+ return 0;
+}
+
+static int pil_gss_init_image(struct pil_desc *pil, const u8 *metadata,
+ size_t size)
+{
+ const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
+ struct gss_data *drv = dev_get_drvdata(pil->dev);
+ drv->start_addr = ehdr->e_entry;
+ return 0;
+}
+
+static int make_gss_proxy_votes(struct device *dev)
+{
+ int ret;
+ struct gss_data *drv = dev_get_drvdata(dev);
+
+ ret = clk_prepare_enable(drv->xo);
+ if (ret) {
+ dev_err(dev, "Failed to enable XO\n");
+ return ret;
+ }
+ schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+ return 0;
+}
+
+static void remove_gss_proxy_votes(struct work_struct *work)
+{
+ struct gss_data *drv = container_of(work, struct gss_data, work.work);
+ clk_disable_unprepare(drv->xo);
+}
+
+static void remove_gss_proxy_votes_now(struct gss_data *drv)
+{
+ flush_delayed_work(&drv->work);
+}
+
+static void gss_init(struct gss_data *drv)
+{
+ void __iomem *base = drv->base;
+
+ /* Supply clocks to GSS. */
+ writel_relaxed(XO_CLK_BRANCH_ENA, GSS_CXO_SRC_CTL);
+ writel_relaxed(SLP_CLK_BRANCH_ENA, GSS_SLP_CLK_CTL);
+
+ /* Deassert GSS reset and clamps. */
+ writel_relaxed(0x0, GSS_RESET);
+ writel_relaxed(0x0, GSS_CLAMP_ENA);
+ mb();
+
+ /*
+ * Configure clock source and dividers for 288MHz core, 144MHz AXI and
+ * 72MHz AHB, all derived from the 288MHz PLL.
+ */
+ writel_relaxed(0x341, base + GSS_CSR_CLK_BLK_CONFIG);
+ writel_relaxed(0x1, base + GSS_CSR_AHB_CLK_SEL);
+
+ /* Assert all GSS resets. */
+ writel_relaxed(0x7F, base + GSS_CSR_RESET);
+
+ /* Enable all bus clocks and wait for resets to propagate. */
+ writel_relaxed(0x1F, base + GSS_CSR_CLK_ENABLE);
+ mb();
+ udelay(1);
+
+ /* Release subsystem from reset, but leave A5 in reset. */
+ writel_relaxed(A5_RESET, base + GSS_CSR_RESET);
+}
+
+static void setup_qgic2_bus_access(void *data)
+{
+ struct gss_data *drv = data;
+ void __iomem *base = drv->base;
+ int i;
+
+ writel_relaxed(0x2, base + GSS_CSR_CFG_HID);
+ for (i = 0; i <= 3; i++)
+ readl_relaxed(drv->qgic2_base);
+}
+
+static int pil_gss_shutdown(struct pil_desc *pil)
+{
+ struct gss_data *drv = dev_get_drvdata(pil->dev);
+ void __iomem *base = drv->base;
+ u32 regval;
+ int ret;
+
+ ret = clk_prepare_enable(drv->xo);
+ if (ret) {
+ dev_err(pil->dev, "Failed to enable XO\n");
+ return ret;
+ }
+
+ /*
+ * Vote PLL on in GSS's voting register and wait for it to enable.
+ * The PLL must be enable to switch the GFMUX to a low-power source.
+ */
+ writel_relaxed(PLL5_VOTE, PLL_ENA_GSS);
+ while ((readl_relaxed(PLL5_STATUS) & PLL_STATUS) == 0)
+ cpu_relax();
+
+ /* Perform one-time GSS initialization. */
+ gss_init(drv);
+
+ /* Assert A5 reset. */
+ regval = readl_relaxed(base + GSS_CSR_RESET);
+ regval |= A5_RESET;
+ writel_relaxed(regval, base + GSS_CSR_RESET);
+
+ /* Power down A5 and NAV. */
+ regval = readl_relaxed(base + GSS_CSR_POWER_UP_DOWN);
+ regval &= ~(A5_POWER_ENA|NAV_POWER_ENA);
+ writel_relaxed(regval, base + GSS_CSR_POWER_UP_DOWN);
+
+ /* Select XO clock source and increase dividers to save power. */
+ regval = readl_relaxed(base + GSS_CSR_CLK_BLK_CONFIG);
+ regval |= 0x3FF;
+ writel_relaxed(regval, base + GSS_CSR_CLK_BLK_CONFIG);
+
+ /* Disable bus clocks. */
+ writel_relaxed(0x1F, base + GSS_CSR_CLK_ENABLE);
+
+ /* Clear GSS PLL votes. */
+ writel_relaxed(0, PLL_ENA_GSS);
+ mb();
+
+ clk_disable_unprepare(drv->xo);
+ remove_gss_proxy_votes_now(drv);
+
+ return 0;
+}
+
+static int pil_gss_reset(struct pil_desc *pil)
+{
+ struct gss_data *drv = dev_get_drvdata(pil->dev);
+ void __iomem *base = drv->base;
+ unsigned long start_addr = drv->start_addr;
+ int ret;
+
+ ret = make_gss_proxy_votes(pil->dev);
+ if (ret)
+ return ret;
+
+ /* Vote PLL on in GSS's voting register and wait for it to enable. */
+ writel_relaxed(PLL5_VOTE, PLL_ENA_GSS);
+ while ((readl_relaxed(PLL5_STATUS) & PLL_STATUS) == 0)
+ cpu_relax();
+
+ /* Perform GSS initialization. */
+ gss_init(drv);
+
+ /* Configure boot address and enable remap. */
+ writel_relaxed(REMAP_ENABLE | (start_addr >> 16),
+ base + GSS_CSR_BOOT_REMAP);
+
+ /* Power up A5 core. */
+ writel_relaxed(A5_POWER_ENA, base + GSS_CSR_POWER_UP_DOWN);
+ while (!(readl_relaxed(base + GSS_CSR_POWER_UP_DOWN) & A5_POWER_STATUS))
+ cpu_relax();
+
+ /*
+ * Apply a 8064 v1.0 workaround to configure QGIC bus access. This must
+ * be done from Krait 0 to configure the Master ID correctly.
+ */
+ ret = smp_call_function_single(0, setup_qgic2_bus_access, drv, 1);
+ if (ret) {
+ pr_err("Failed to configure QGIC2 bus access\n");
+ pil_gss_shutdown(pil);
+ return ret;
+ }
+
+ /* Release A5 from reset. */
+ writel_relaxed(0x0, base + GSS_CSR_RESET);
+
+ return 0;
+}
+
+static struct pil_reset_ops pil_gss_ops = {
+ .init_image = pil_gss_init_image,
+ .verify_blob = nop_verify_blob,
+ .auth_and_reset = pil_gss_reset,
+ .shutdown = pil_gss_shutdown,
+};
+
+static void configure_gss_pll(struct gss_data *drv)
+{
+ u32 regval, is_pll_enabled;
+
+ /* Check if PLL5 is enabled by FSM. */
+ is_pll_enabled = readl_relaxed(PLL5_STATUS) & PLL_STATUS;
+ if (!is_pll_enabled) {
+ /* Enable XO reference for PLL5 */
+ clk_prepare_enable(drv->xo);
+
+ /*
+ * Assert a vote to hold PLL5 on in RPM register until other
+ * voters are in place.
+ */
+ regval = readl_relaxed(PLL_ENA_RPM);
+ regval |= PLL5_VOTE;
+ writel_relaxed(regval, PLL_ENA_RPM);
+
+ /* Ref clk = 27MHz and program pll5 to 288MHz */
+ writel_relaxed(0xF, PLL5_L_VAL);
+ writel_relaxed(0x0, PLL5_M_VAL);
+ writel_relaxed(0x1, PLL5_N_VAL);
+
+ regval = readl_relaxed(PLL5_CONFIG);
+ /* Disable the MN accumulator and enable the main output. */
+ regval &= ~BIT(22);
+ regval |= BIT(23);
+
+ /* Set pre-divider and post-divider values to 1 and 1 */
+ regval &= ~BIT(19);
+ regval &= ~(BIT(21)|BIT(20));
+
+ /* Set VCO frequency */
+ regval &= ~(BIT(17)|BIT(16));
+ writel_relaxed(regval, PLL5_CONFIG);
+
+ regval = readl_relaxed(PLL5_MODE);
+ /* De-assert reset to FSM */
+ regval &= ~BIT(21);
+ writel_relaxed(regval, PLL5_MODE);
+
+ /* Program bias count */
+ regval &= ~(0x3F << 14);
+ regval |= (0x1 << 14);
+ writel_relaxed(regval, PLL5_MODE);
+
+ /* Program lock count */
+ regval &= ~(0x3F << 8);
+ regval |= (0x8 << 8);
+ writel_relaxed(regval, PLL5_MODE);
+
+ /* Enable PLL FSM voting */
+ regval |= BIT(20);
+ writel_relaxed(regval, PLL5_MODE);
+ }
+}
+
+static int __devinit pil_gss_probe(struct platform_device *pdev)
+{
+ struct gss_data *drv;
+ struct resource *res;
+ struct pil_desc *desc;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EINVAL;
+
+ drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
+ if (!drv)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, drv);
+
+ drv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!drv->base)
+ return -ENOMEM;
+
+ desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res)
+ return -EINVAL;
+
+ drv->qgic2_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!drv->qgic2_base)
+ return -ENOMEM;
+
+ drv->xo = clk_get(&pdev->dev, "xo");
+ if (IS_ERR(drv->xo))
+ return PTR_ERR(drv->xo);
+
+ desc->name = "gss";
+ desc->dev = &pdev->dev;
+
+ desc->ops = &pil_gss_ops;
+ dev_info(&pdev->dev, "using non-secure boot\n");
+
+ INIT_DELAYED_WORK(&drv->work, remove_gss_proxy_votes);
+
+ /* FIXME: Remove when PLL is configured by bootloaders. */
+ configure_gss_pll(drv);
+
+ ret = msm_pil_register(desc);
+ if (ret) {
+ flush_delayed_work_sync(&drv->work);
+ clk_put(drv->xo);
+ }
+ return ret;
+}
+
+static int __devexit pil_gss_remove(struct platform_device *pdev)
+{
+ struct gss_data *drv = platform_get_drvdata(pdev);
+ flush_delayed_work_sync(&drv->work);
+ clk_put(drv->xo);
+ return 0;
+}
+
+static struct platform_driver pil_gss_driver = {
+ .probe = pil_gss_probe,
+ .remove = __devexit_p(pil_gss_remove),
+ .driver = {
+ .name = "pil_gss",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init pil_gss_init(void)
+{
+ return platform_driver_register(&pil_gss_driver);
+}
+module_init(pil_gss_init);
+
+static void __exit pil_gss_exit(void)
+{
+ platform_driver_unregister(&pil_gss_driver);
+}
+module_exit(pil_gss_exit);
+
+MODULE_DESCRIPTION("Support for booting the GSS processor");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
index 0ddba89..4b8b7a6 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
*
* Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
*
@@ -196,8 +196,10 @@
static void audplay_config_hostpcm(struct audio *audio);
static void audplay_buffer_refresh(struct audio *audio);
static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audadpcm_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload);
+#endif
/* must be called with audio->lock held */
static int audio_enable(struct audio *audio)
@@ -1433,6 +1435,7 @@
return 0;
}
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audadpcm_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload)
{
@@ -1461,7 +1464,6 @@
wake_up(&audio->event_wait);
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
static void audadpcm_suspend(struct early_suspend *h)
{
struct audadpcm_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
index 85a3daa..a09b71b 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
@@ -1,7 +1,7 @@
/*
* amrnb audio decoder device
*
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
*
@@ -194,8 +194,10 @@
static void audamrnb_config_hostpcm(struct audio *audio);
static void audamrnb_buffer_refresh(struct audio *audio);
static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audamrnb_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload);
+#endif
/* must be called with audio->lock held */
static int audamrnb_enable(struct audio *audio)
@@ -1330,6 +1332,7 @@
return 0;
}
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audamrnb_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload)
{
@@ -1358,7 +1361,6 @@
wake_up(&audio->event_wait);
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
static void audamrnb_suspend(struct early_suspend *h)
{
struct audamrnb_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
index d6cf21d..48e9a9f 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
@@ -1,6 +1,6 @@
/* amrwb audio decoder device
*
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
*
@@ -195,8 +195,10 @@
static void audamrwb_config_hostpcm(struct audio *audio);
static void audamrwb_buffer_refresh(struct audio *audio);
static void audamrwb_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audamrwb_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload);
+#endif
/* must be called with audio->lock held */
static int audamrwb_enable(struct audio *audio)
@@ -1414,6 +1416,7 @@
return 0;
}
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audamrwb_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload)
{
@@ -1442,7 +1445,6 @@
wake_up(&audio->event_wait);
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
static void audamrwb_suspend(struct early_suspend *h)
{
struct audamrwb_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
index e5261b5..9b5694d 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This code also borrows from audio_aac.c, which is
* Copyright (C) 2008 Google, Inc.
@@ -189,8 +189,10 @@
static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg);
static void audevrc_config_hostpcm(struct audio *audio);
static void audevrc_buffer_refresh(struct audio *audio);
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audevrc_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload);
+#endif
/* must be called with audio->lock held */
static int audevrc_enable(struct audio *audio)
@@ -1324,6 +1326,7 @@
return 0;
}
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audevrc_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload)
{
@@ -1352,7 +1355,6 @@
wake_up(&audio->event_wait);
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
static void audevrc_suspend(struct early_suspend *h)
{
struct audevrc_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
index 0e61e84..c639833 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -112,6 +112,7 @@
int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \
res; \
})
+struct audio;
struct buffer {
void *data;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
index 139c16c..b22820b 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -101,6 +101,8 @@
res; \
})
+struct audio;
+
struct buffer {
void *data;
unsigned size;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
index f3f0619..ce5d421 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
@@ -1,7 +1,7 @@
/*
* qcelp 13k audio decoder device
*
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This code is based in part on audio_mp3.c, which is
* Copyright (C) 2008 Google, Inc.
@@ -184,8 +184,10 @@
static void audqcelp_config_hostpcm(struct audio *audio);
static void audqcelp_buffer_refresh(struct audio *audio);
static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audqcelp_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload);
+#endif
/* must be called with audio->lock held */
static int audqcelp_enable(struct audio *audio)
@@ -1326,6 +1328,7 @@
return 0;
}
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audqcelp_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload)
{
@@ -1354,7 +1357,6 @@
wake_up(&audio->event_wait);
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
static void audqcelp_suspend(struct early_suspend *h)
{
struct audqcelp_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wma.c b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
index 464f66e..f29b078 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
*
* Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
*
@@ -200,9 +200,10 @@
static void audplay_config_hostpcm(struct audio *audio);
static void audplay_buffer_refresh(struct audio *audio);
static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audwma_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload);
-
+#endif
/* must be called with audio->lock held */
static int audio_enable(struct audio *audio)
{
@@ -1472,6 +1473,7 @@
return 0;
}
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audwma_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload)
{
@@ -1500,7 +1502,6 @@
wake_up(&audio->event_wait);
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
static void audwma_suspend(struct early_suspend *h)
{
struct audwma_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
index 878237e..cf25359 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
*
* Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
*
@@ -200,8 +200,10 @@
static void audplay_config_hostpcm(struct audio *audio);
static void audplay_buffer_refresh(struct audio *audio);
static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audwmapro_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload);
+#endif
/* must be called with audio->lock held */
static int audio_enable(struct audio *audio)
@@ -1484,6 +1486,7 @@
return 0;
}
+#ifdef CONFIG_HAS_EARLYSUSPEND
static void audwmapro_post_event(struct audio *audio, int type,
union msm_audio_event_payload payload)
{
@@ -1512,7 +1515,6 @@
wake_up(&audio->event_wait);
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
static void audwmapro_suspend(struct early_suspend *h)
{
struct audwmapro_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 326faef..0aa1358 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -167,23 +167,26 @@
uint32_t val = 0;
uint32_t timeout = 0;
void *reg = NULL;
+ void *saw_bases[] = {
+ 0,
+ MSM_SAW1_BASE,
+ MSM_SAW2_BASE,
+ MSM_SAW3_BASE
+ };
- if (cpu >= num_possible_cpus())
+ if (cpu == 0 || cpu >= num_possible_cpus())
return -EINVAL;
- switch (cpu) {
- case 1:
- reg = MSM_SAW1_BASE;
- break;
- case 0:
- default:
- return -EFAULT;
- }
+ reg = saw_bases[cpu];
if (cpu_is_msm8960() || cpu_is_msm8930()) {
val = 0xB0;
reg += 0x14;
timeout = 512;
+ } else if (cpu_is_apq8064()) {
+ val = 0xA4;
+ reg += 0x14;
+ timeout = 512;
} else {
return -ENOSYS;
}
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index b44dccc..805e2b6 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -565,6 +565,7 @@
kgsl_mmu_stop(device);
device->ftbl->irqctrl(device, 0);
+ kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
/* Power down the device */
kgsl_pwrctrl_disable(device);
diff --git a/drivers/mfd/pm8821-core.c b/drivers/mfd/pm8821-core.c
index 8a556bd..ffcef99 100644
--- a/drivers/mfd/pm8821-core.c
+++ b/drivers/mfd/pm8821-core.c
@@ -29,7 +29,7 @@
#define REG_IRQ_BASE 0x1BB
#define PM8821_VERSION_MASK 0xFFF0
-#define PM8821_VERSION_VALUE 0x07F0
+#define PM8821_VERSION_VALUE 0x0BF0
#define PM8821_REVISION_MASK 0x000F
#define SINGLE_IRQ_RESOURCE(_name, _irq) \
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index d06a637..a306357 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -75,4 +75,10 @@
help
OpenFirmware PCI bus accessors
+config OF_SPMI
+ def_tristate SPMI
+ depends on SPMI
+ help
+ OpenFirmware SPMI bus accessors
+
endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index f7861ed..2087c5e 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,3 +10,4 @@
obj-$(CONFIG_OF_SPI) += of_spi.o
obj-$(CONFIG_OF_MDIO) += of_mdio.o
obj-$(CONFIG_OF_PCI) += of_pci.o
+obj-$(CONFIG_OF_SPMI) += of_spmi.o
diff --git a/drivers/of/of_spmi.c b/drivers/of/of_spmi.c
new file mode 100644
index 0000000..9f2a396
--- /dev/null
+++ b/drivers/of/of_spmi.c
@@ -0,0 +1,160 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/spmi.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_spmi.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+/**
+ * Allocate resources for a child of a spmi-container node.
+ */
+static int of_spmi_allocate_resources(struct spmi_controller *ctrl,
+ struct spmi_boardinfo *info,
+ struct device_node *node,
+ uint32_t num_reg)
+{
+ int i, num_irq = 0;
+ uint64_t size;
+ uint32_t flags;
+ struct resource *res;
+ const __be32 *addrp;
+ struct of_irq oirq;
+
+ while (of_irq_map_one(node, num_irq, &oirq) == 0)
+ num_irq++;
+
+ if (num_irq || num_reg) {
+ res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
+ if (!res)
+ return -ENOMEM;
+
+ info->num_resources = num_reg + num_irq;
+ info->resource = res;
+ for (i = 0; i < num_reg; i++, res++) {
+ /* Addresses are always 16 bits */
+ addrp = of_get_address(node, i, &size, &flags);
+ BUG_ON(!addrp);
+ res->start = be32_to_cpup(addrp);
+ res->end = res->start + size - 1;
+ res->flags = flags;
+ }
+ WARN_ON(of_irq_to_resource_table(node, res, num_irq) !=
+ num_irq);
+ }
+
+ return 0;
+}
+
+static int of_spmi_create_device(struct spmi_controller *ctrl,
+ struct spmi_boardinfo *info,
+ struct device_node *node)
+{
+ void *result;
+ int rc;
+
+ rc = of_modalias_node(node, info->name, sizeof(info->name));
+ if (rc < 0) {
+ dev_err(&ctrl->dev, "of_spmi modalias failure on %s\n",
+ node->full_name);
+ return rc;
+ }
+
+ info->of_node = of_node_get(node);
+ result = spmi_new_device(ctrl, info);
+
+ if (result == NULL) {
+ dev_err(&ctrl->dev, "of_spmi: Failure registering %s\n",
+ node->full_name);
+ of_node_put(node);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static void of_spmi_walk_container_children(struct spmi_controller *ctrl,
+ struct spmi_boardinfo *info,
+ struct device_node *container)
+{
+ struct device_node *node;
+ uint64_t size;
+ uint32_t flags, num_reg = 0;
+ int rc;
+
+ for_each_child_of_node(container, node) {
+ /*
+ * We can't use of_address_to_resource here since it includes
+ * address translation; and address translation assumes that no
+ * parent buses have a size-cell of 0. But SPMI does have a
+ * size-cell of 0.
+ */
+ while (of_get_address(node, num_reg, &size, &flags) != NULL)
+ num_reg++;
+
+ rc = of_spmi_allocate_resources(ctrl, info, node, num_reg);
+ if (rc) {
+ dev_err(&ctrl->dev, "%s: unable to allocate"
+ " resources\n", __func__);
+ return;
+ }
+ rc = of_spmi_create_device(ctrl, info, node);
+ if (rc) {
+ dev_err(&ctrl->dev, "%s: unable to create device for"
+ " node %s\n", __func__, node->full_name);
+ return;
+ }
+ }
+}
+
+int of_spmi_register_devices(struct spmi_controller *ctrl)
+{
+ struct device_node *node;
+
+ /* Only register child devices if the ctrl has a node pointer set */
+ if (!ctrl->dev.of_node)
+ return -ENODEV;
+
+ for_each_child_of_node(ctrl->dev.of_node, node) {
+ struct spmi_boardinfo info = {};
+ const __be32 *slave_id;
+ int len, rc;
+
+ slave_id = of_get_property(node, "reg", &len);
+ if (!slave_id) {
+ dev_err(&ctrl->dev, "of_spmi: invalid sid "
+ "on %s\n", node->full_name);
+ continue;
+ }
+
+ info.slave_id = be32_to_cpup(slave_id);
+
+ if (of_get_property(node, "spmi-dev-container", NULL)) {
+ of_spmi_walk_container_children(ctrl, &info, node);
+ continue;
+ } else {
+ rc = of_spmi_allocate_resources(ctrl, &info, node, 0);
+ if (rc)
+ continue;
+ of_spmi_create_device(ctrl, &info, node);
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(of_spmi_register_devices);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index aa67c8c..6c5b380 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -354,8 +354,13 @@
static void msm_slim_put_ctrl(struct msm_slim_ctrl *dev)
{
#ifdef CONFIG_PM_RUNTIME
+ int ref;
pm_runtime_mark_last_busy(dev->dev);
- pm_runtime_put(dev->dev);
+ ref = atomic_read(&dev->dev->power.usage_count);
+ if (ref <= 0)
+ dev_err(dev->dev, "reference count mismatch:%d", ref);
+ else
+ pm_runtime_put(dev->dev);
#endif
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index d54c01e..75df48d 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -10,10 +10,12 @@
* GNU General Public License for more details.
*
*/
+#include <linux/ion.h>
#include <mach/msm_memtypes.h>
#include "vcd_ddl.h"
#include "vcd_ddl_shared_mem.h"
+
struct ddl_context *ddl_get_context(void)
{
static struct ddl_context ddl_context;
@@ -253,6 +255,15 @@
memset(frame[i].vcd_frm.virtual + luma_size,
0x80808080,
frame[i].vcd_frm.alloc_len - luma_size);
+ if (frame[i].vcd_frm.ion_flag == CACHED) {
+ clean_and_invalidate_caches(
+ (unsigned long)frame[i].
+ vcd_frm.virtual,
+ (unsigned long)frame[i].
+ vcd_frm.alloc_len,
+ (unsigned long)frame[i].
+ vcd_frm.physical);
+ }
} else {
DDL_MSG_ERROR("luma size error");
return VCD_ERR_FAIL;
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 8a2f534..b300fbc 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -235,6 +235,7 @@
struct file *file;
s32 buffer_index = -1;
enum vdec_picture pic_type;
+ u32 ion_flag = 0;
if (!client_ctx || !vcd_frame_data) {
ERR("vid_dec_input_frame_done() NULL pointer\n");
@@ -268,7 +269,6 @@
&phy_addr, &pmem_fd, &file,
&buffer_index) ||
(vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) {
-
/* Buffer address in user space */
vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr =
(u8 *) user_vaddr;
@@ -334,7 +334,15 @@
ERR("vid_dec_output_frame_done UVA can not be found\n");
vdec_msg->vdec_msg_info.status_code = VDEC_S_EFATAL;
}
-
+ if (vcd_frame_data->data_len > 0) {
+ ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
+ pmem_fd, kernel_vaddr, buffer_index);
+ if (ion_flag == CACHED) {
+ invalidate_caches(kernel_vaddr,
+ (unsigned long)vcd_frame_data->data_len,
+ phy_addr);
+ }
+ }
mutex_lock(&client_ctx->msg_queue_lock);
list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
mutex_unlock(&client_ctx->msg_queue_lock);
@@ -1034,7 +1042,6 @@
__func__, buffer_info->buffer.bufferaddr);
return false;
}
-
vcd_status = vcd_set_buffer(client_ctx->vcd_handle,
buffer, (u8 *) kernel_vaddr,
buffer_info->buffer.buffer_len);
@@ -1180,6 +1187,7 @@
struct file *file;
s32 buffer_index = -1;
u32 vcd_status = VCD_ERR_FAIL;
+ u32 ion_flag = 0;
if (!client_ctx || !input_frame_info)
return false;
@@ -1207,7 +1215,18 @@
vcd_input_buffer.flags = input_frame_info->flags;
vcd_input_buffer.desc_buf = desc_buf;
vcd_input_buffer.desc_size = desc_size;
-
+ if (vcd_input_buffer.data_len > 0) {
+ ion_flag = vidc_get_fd_info(client_ctx,
+ BUFFER_TYPE_INPUT,
+ pmem_fd,
+ kernel_vaddr,
+ buffer_index);
+ if (ion_flag == CACHED) {
+ clean_caches(kernel_vaddr,
+ (unsigned long)vcd_input_buffer.data_len,
+ phy_addr);
+ }
+ }
vcd_status = vcd_decode_frame(client_ctx->vcd_handle,
&vcd_input_buffer);
if (!vcd_status)
@@ -1250,7 +1269,10 @@
vcd_frame.virtual = (u8 *) kernel_vaddr;
vcd_frame.frm_clnt_data = (u32) fill_buffer_cmd->client_data;
vcd_frame.alloc_len = fill_buffer_cmd->buffer.buffer_len;
-
+ vcd_frame.ion_flag = vidc_get_fd_info(client_ctx,
+ BUFFER_TYPE_OUTPUT,
+ pmem_fd, kernel_vaddr,
+ buffer_index);
vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle,
&vcd_frame);
if (!vcd_status)
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 97fc758..cc6606c 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -197,6 +197,7 @@
int pmem_fd;
struct file *file;
s32 buffer_index = -1;
+ u32 ion_flag = 0;
if (!client_ctx || !vcd_frame_data) {
ERR("vid_enc_input_frame_done() NULL pointer\n");
@@ -259,7 +260,15 @@
venc_msg->venc_msg_info.statuscode =
VEN_S_EFATAL;
}
-
+ if (venc_msg->venc_msg_info.buf.len > 0) {
+ ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
+ pmem_fd, kernel_vaddr, buffer_index);
+ if (ion_flag == CACHED) {
+ clean_and_invalidate_caches(kernel_vaddr,
+ (unsigned long)venc_msg->venc_msg_info.buf.len,
+ phy_addr);
+ }
+ }
mutex_lock(&client_ctx->msg_queue_lock);
list_add_tail(&venc_msg->list, &client_ctx->msg_queue);
mutex_unlock(&client_ctx->msg_queue_lock);
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index 47b0f66..e3bb9db 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -1609,6 +1609,7 @@
int pmem_fd;
struct file *file;
s32 buffer_index = -1;
+ u32 ion_flag = 0;
u32 vcd_status = VCD_ERR_FAIL;
@@ -1640,6 +1641,18 @@
/* Rely on VCD using the same flags as OMX */
vcd_input_buffer.flags = input_frame_info->flags;
+ ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_INPUT,
+ pmem_fd, kernel_vaddr, buffer_index);
+
+ if (vcd_input_buffer.data_len > 0) {
+ if (ion_flag == CACHED) {
+ clean_caches(
+ (unsigned long) vcd_input_buffer.virtual,
+ (unsigned long) vcd_input_buffer.data_len,
+ (phy_addr + input_frame_info->offset));
+ }
+ }
+
vcd_status = vcd_encode_frame(client_ctx->vcd_handle,
&vcd_input_buffer);
if (!vcd_status)
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index d24d43c..cd3f954 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -364,6 +364,26 @@
}
EXPORT_SYMBOL(vidc_release_firmware);
+u32 vidc_get_fd_info(struct video_client_ctx *client_ctx,
+ enum buffer_dir buffer, int pmem_fd,
+ unsigned long kvaddr, int index)
+{
+ struct buf_addr_table *buf_addr_table;
+ u32 rc = 0;
+ if (!client_ctx)
+ return false;
+ if (buffer == BUFFER_TYPE_INPUT)
+ buf_addr_table = client_ctx->input_buf_addr_table;
+ else
+ buf_addr_table = client_ctx->output_buf_addr_table;
+ if (buf_addr_table[index].pmem_fd == pmem_fd) {
+ if (buf_addr_table[index].kernel_vaddr == kvaddr)
+ rc = buf_addr_table[index].buff_ion_flag;
+ }
+ return rc;
+}
+EXPORT_SYMBOL(vidc_get_fd_info);
+
u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx,
enum buffer_dir buffer,
u32 search_with_user_vaddr,
@@ -459,7 +479,7 @@
struct msm_mapped_buffer *mapped_buffer = NULL;
size_t ion_len;
struct ion_handle *buff_ion_handle = NULL;
- unsigned long ionflag;
+ unsigned long ionflag = 0;
if (!client_ctx || !length)
return false;
@@ -556,10 +576,13 @@
buf_addr_table[*num_of_buffers].phy_addr = phys_addr;
buf_addr_table[*num_of_buffers].buff_ion_handle =
buff_ion_handle;
+ buf_addr_table[*num_of_buffers].buff_ion_flag =
+ ionflag;
*num_of_buffers = *num_of_buffers + 1;
DBG("%s() : client_ctx = %p, user_virt_addr = 0x%08lx, "
- "kernel_vaddr = 0x%08lx inserted!", __func__,
- client_ctx, user_vaddr, *kernel_vaddr);
+ "kernel_vaddr = 0x%08lx phys_addr=%lu inserted!",
+ __func__, client_ctx, user_vaddr, *kernel_vaddr,
+ phys_addr);
}
mutex_unlock(&client_ctx->enrty_queue_lock);
return true;
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.h b/drivers/video/msm/vidc/common/init/vidc_init.h
index 717d0c8..ced99ff 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.h
+++ b/drivers/video/msm/vidc/common/init/vidc_init.h
@@ -28,6 +28,7 @@
unsigned long user_vaddr;
unsigned long kernel_vaddr;
unsigned long phy_addr;
+ unsigned long buff_ion_flag;
struct ion_handle *buff_ion_handle;
int pmem_fd;
struct file *file;
@@ -63,6 +64,9 @@
void __iomem *vidc_get_ioaddr(void);
int vidc_load_firmware(void);
void vidc_release_firmware(void);
+u32 vidc_get_fd_info(struct video_client_ctx *client_ctx,
+ enum buffer_dir buffer, int pmem_fd,
+ unsigned long kvaddr, int index);
u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx,
enum buffer_dir buffer, u32 search_with_user_vaddr,
unsigned long *user_vaddr, unsigned long *kernel_vaddr,
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.h b/drivers/video/msm/vidc/common/vcd/vcd_api.h
index badab1e..9580ece 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_api.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_api.h
@@ -56,6 +56,7 @@
struct vcd_frame_data {
u8 *virtual;
u8 *physical;
+ u32 ion_flag;
u32 alloc_len;
u32 data_len;
u32 offset;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index b5fcc1c..509b897 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -188,6 +188,36 @@
}
+u32 vcd_get_ion_flag(struct video_client_ctx *client_ctx,
+ unsigned long kernel_vaddr)
+{
+ unsigned long phy_addr, user_vaddr;
+ int pmem_fd;
+ struct file *file;
+ s32 buffer_index = -1;
+ u32 ion_flag = 0;
+
+ if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT,
+ false, &user_vaddr, &kernel_vaddr,
+ &phy_addr, &pmem_fd, &file,
+ &buffer_index)) {
+
+ ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_INPUT,
+ pmem_fd, kernel_vaddr, buffer_index);
+ return ion_flag;
+ } else if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+ false, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file,
+ &buffer_index)) {
+ ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
+ pmem_fd, kernel_vaddr, buffer_index);
+ return ion_flag;
+ } else {
+ VCD_MSG_ERROR("Couldn't get ion flag");
+ return 0;
+ }
+
+}
+
void vcd_reset_device_channels(struct vcd_dev_ctxt *dev_ctxt)
{
dev_ctxt->ddl_frame_ch_free = dev_ctxt->ddl_frame_ch_depth;
@@ -523,6 +553,7 @@
{
struct vcd_buffer_entry *buf_entry;
u8 *physical;
+ u32 ion_flag = 0;
buf_entry = vcd_find_buffer_pool_entry(buf_pool, buffer);
if (buf_entry) {
@@ -534,6 +565,9 @@
physical = (u8 *) vcd_pmem_get_physical(
cctxt->client_data, (unsigned long)buffer);
+ ion_flag = vcd_get_ion_flag(cctxt->client_data,
+ (unsigned long)buffer);
+
if (!physical) {
VCD_MSG_ERROR("Couldn't get physical address");
return VCD_ERR_BAD_POINTER;
@@ -548,7 +582,6 @@
VCD_MSG_ERROR("Can't allocate buffer pool is full");
return VCD_ERR_FAIL;
}
-
buf_entry->virtual = buffer;
buf_entry->physical = physical;
buf_entry->sz = buf_size;
@@ -557,6 +590,7 @@
buf_entry->frame.virtual = buf_entry->virtual;
buf_entry->frame.physical = buf_entry->physical;
+ buf_entry->frame.ion_flag = ion_flag;
buf_pool->validated++;
diff --git a/include/linux/of_spmi.h b/include/linux/of_spmi.h
new file mode 100644
index 0000000..d07ce63
--- /dev/null
+++ b/include/linux/of_spmi.h
@@ -0,0 +1,23 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/spmi.h>
+#include <linux/of_irq.h>
+
+#ifdef CONFIG_OF_SPMI
+int of_spmi_register_devices(struct spmi_controller *ctrl);
+#else
+static int of_spmi_register_devices(struct spmi_controller *ctrl)
+{
+ return -ENXIO;
+}
+#endif /* CONFIG_OF_SPMI */
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index fea11d9..42e7935 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -249,6 +249,28 @@
.ops = &msm_fe_dai_ops,
.name = "HDMI_HOSTLESS"
},
+ {
+ .playback = {
+ .stream_name = "AUXPCM Hostless Playback",
+ .rates = SNDRV_PCM_RATE_8000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 1,
+ .rate_min = 8000,
+ .rate_max = 8000,
+ },
+ .capture = {
+ .stream_name = "AUXPCM Hostless Capture",
+ .rates = SNDRV_PCM_RATE_8000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 1,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "AUXPCM_HOSTLESS",
+ },
};
static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 27a27ec..c7d7004 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -23,7 +23,6 @@
#include <sound/soc.h>
#include <sound/apr_audio.h>
#include <sound/q6afe.h>
-#include <sound/q6adm.h>
#include <sound/msm-dai-q6.h>
#include <mach/clk.h>
@@ -466,10 +465,6 @@
struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
int rc = 0;
- rc = adm_close(dai->id);
- if (IS_ERR_VALUE(rc))
- dev_err(dai->dev, "fail to close ADM COPP\n");
-
pr_debug("%s: dai->id = %d", __func__, dai->id);
if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 94ed504..2b4999f 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -937,6 +937,18 @@
SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+};
+
+static const struct snd_kcontrol_new auxpcm_rx_port_mixer_controls[] = {
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
};
static const struct snd_kcontrol_new fm_switch_mixer_controls =
@@ -1154,6 +1166,10 @@
SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture",
+ 0, 0, 0, 0),
/* Backend AIF */
/* Stream name equals to backend dai link stream name
@@ -1254,6 +1270,9 @@
SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer",
SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls,
ARRAY_SIZE(sbus_0_rx_port_mixer_controls)),
+ SND_SOC_DAPM_MIXER("AUXPCM_RX Port Mixer",
+ SND_SOC_NOPM, 0, 0, auxpcm_rx_port_mixer_controls,
+ ARRAY_SIZE(auxpcm_rx_port_mixer_controls)),
};
static const struct snd_soc_dapm_route intercon[] = {
@@ -1377,9 +1396,16 @@
{"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"},
{"INT_FM_RX", NULL, "INTFM_DL_HL"},
{"INTFM_UL_HL", NULL, "INT_FM_TX"},
+ {"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"},
+ {"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"},
{"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"},
+
+ {"AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"AUX_PCM_RX", NULL, "AUXPCM_RX Port Mixer"},
};
static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 75bb75f..578f819 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -716,16 +716,8 @@
},
};
-static struct snd_soc_dsp_link slimbus0_hl_media = {
- .playback = true,
- .capture = true,
- .trigger = {
- SND_SOC_DSP_TRIGGER_POST,
- SND_SOC_DSP_TRIGGER_POST
- },
-};
-
-static struct snd_soc_dsp_link int_fm_hl_media = {
+/* bi-directional media definition for hostless PCM device */
+static struct snd_soc_dsp_link bidir_hl_media = {
.playback = true,
.capture = true,
.trigger = {
@@ -985,7 +977,7 @@
.cpu_dai_name = "SLIMBUS0_HOSTLESS",
.platform_name = "msm-pcm-hostless",
.dynamic = 1,
- .dsp_link = &slimbus0_hl_media,
+ .dsp_link = &bidir_hl_media,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ignore_suspend = 1,
/* .be_id = do not care */
@@ -996,7 +988,7 @@
.cpu_dai_name = "INT_FM_HOSTLESS",
.platform_name = "msm-pcm-hostless",
.dynamic = 1,
- .dsp_link = &int_fm_hl_media,
+ .dsp_link = &bidir_hl_media,
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ignore_suspend = 1,
/* .be_id = do not care */
@@ -1028,6 +1020,16 @@
.dsp_link = &lpa_fe_media,
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
},
+ {
+ .name = "AUXPCM Hostless",
+ .stream_name = "AUXPCM Hostless",
+ .cpu_dai_name = "AUXPCM_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dsp_link = &bidir_hl_media,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ },
/* HDMI Hostless */
{
.name = "HDMI_RX_HOSTLESS",