Merge "msm: msm7627a_defconfig: Enable HIGHMEM support" 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/common/gic.c b/arch/arm/common/gic.c
index 0455878..bb4d971 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -65,6 +65,7 @@
u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
+ u32 saved_dist_pri[DIV_ROUND_UP(1020, 4)];
u32 __percpu *saved_ppi_enable;
u32 __percpu *saved_ppi_conf;
#endif
@@ -79,6 +80,10 @@
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
+#ifdef CONFIG_CPU_PM
+static unsigned int saved_dist_ctrl, saved_cpu_ctrl;
+#endif
+
/* Address of GIC 0 CPU interface */
void __iomem *gic_cpu_base_addr __read_mostly;
@@ -151,6 +156,26 @@
return d->hwirq;
}
+#ifdef CONFIG_CPU_V7
+static const inline bool is_cpu_secure(void)
+{
+ unsigned int dscr;
+
+ asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (dscr));
+
+ /* BIT(18) - NS bit; 1 = NS; 0 = S */
+ if (BIT(18) & dscr)
+ return false;
+ else
+ return true;
+}
+#else
+static const inline bool is_cpu_secure(void)
+{
+ return false;
+}
+#endif
+
/*
* Routines to acknowledge, disable and enable interrupts
*/
@@ -506,6 +531,14 @@
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
/*
+ * Set NS/S.
+ */
+ if (is_cpu_secure())
+ for (i = 32; i < gic_irqs; i += 32)
+ writel_relaxed(0xFFFFFFFF,
+ base + GIC_DIST_ISR + i * 4 / 32);
+
+ /*
* Set priority on all global interrupts.
*/
for (i = 32; i < gic_irqs; i += 4)
@@ -537,7 +570,11 @@
gic->max_irq = gic_irqs;
- writel_relaxed(1, base + GIC_DIST_CTRL);
+ if (is_cpu_secure())
+ writel_relaxed(3, base + GIC_DIST_CTRL);
+ else
+ writel_relaxed(1, base + GIC_DIST_CTRL);
+
mb();
}
@@ -554,6 +591,10 @@
writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
+ /* Set NS/S */
+ if (is_cpu_secure())
+ writel_relaxed(0xFFFFFFFF, dist_base + GIC_DIST_ISR);
+
/*
* Set priority on PPI and SGI interrupts
*/
@@ -561,7 +602,11 @@
writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
- writel_relaxed(1, base + GIC_CPU_CTRL);
+
+ if (is_cpu_secure())
+ writel_relaxed(0xF, base + GIC_CPU_CTRL);
+ else
+ writel_relaxed(1, base + GIC_CPU_CTRL);
mb();
}
@@ -587,6 +632,8 @@
if (!dist_base)
return;
+ saved_dist_ctrl = readl_relaxed(dist_base + GIC_DIST_CTRL);
+
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
gic_data[gic_nr].saved_spi_conf[i] =
readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
@@ -595,6 +642,10 @@
gic_data[gic_nr].saved_spi_target[i] =
readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4);
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+ gic_data[gic_nr].saved_dist_pri[i] =
+ readl_relaxed(dist_base + GIC_DIST_PRI + i * 4);
+
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
gic_data[gic_nr].saved_spi_enable[i] =
readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
@@ -629,7 +680,7 @@
dist_base + GIC_DIST_CONFIG + i * 4);
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
- writel_relaxed(0xa0a0a0a0,
+ writel_relaxed(gic_data[gic_nr].saved_dist_pri[i],
dist_base + GIC_DIST_PRI + i * 4);
for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
@@ -640,7 +691,7 @@
writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
dist_base + GIC_DIST_ENABLE_SET + i * 4);
- writel_relaxed(1, dist_base + GIC_DIST_CTRL);
+ writel_relaxed(saved_dist_ctrl, dist_base + GIC_DIST_CTRL);
}
static void gic_cpu_save(unsigned int gic_nr)
@@ -659,6 +710,12 @@
if (!dist_base || !cpu_base)
return;
+ saved_cpu_ctrl = readl_relaxed(cpu_base + GIC_CPU_CTRL);
+
+ for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
+ gic_data[gic_nr].saved_dist_pri[i] = readl_relaxed(dist_base +
+ GIC_DIST_PRI + i * 4);
+
ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
@@ -694,10 +751,11 @@
writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
- writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
+ writel_relaxed(gic_data[gic_nr].saved_dist_pri[i],
+ dist_base + GIC_DIST_PRI + i * 4);
writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
- writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
+ writel_relaxed(saved_cpu_ctrl, cpu_base + GIC_CPU_CTRL);
}
static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
@@ -884,12 +942,17 @@
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
{
int cpu;
+ unsigned long sgir;
unsigned long map = 0;
/* Convert our logical CPU mask into a physical one. */
for_each_cpu(cpu, mask)
map |= 1 << cpu_logical_map(cpu);
+ sgir = (map << 16) | irq;
+ if (is_cpu_secure())
+ sgir |= (1 << 15);
+
/*
* Ensure that stores to Normal memory are visible to the
* other CPUs before issuing the IPI.
@@ -897,11 +960,40 @@
dsb();
/* this always happens on GIC0 */
- writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
+ writel_relaxed(sgir,
+ gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
mb();
}
#endif
+void gic_set_irq_secure(unsigned int irq)
+{
+ unsigned int gicd_isr_reg, gicd_pri_reg;
+ unsigned int mask = 0xFFFFFF00;
+ struct gic_chip_data *gic_data = &gic_data[0];
+ struct irq_data *d = irq_get_irq_data(irq);
+
+ if (is_cpu_secure()) {
+ raw_spin_lock(&irq_controller_lock);
+ gicd_isr_reg = readl_relaxed(gic_dist_base(d) +
+ GIC_DIST_ISR + gic_irq(d) / 32 * 4);
+ gicd_isr_reg &= ~BIT(gic_irq(d) % 32);
+ writel_relaxed(gicd_isr_reg, gic_dist_base(d) +
+ GIC_DIST_ISR + gic_irq(d) / 32 * 4);
+ /* Also increase the priority of that irq */
+ gicd_pri_reg = readl_relaxed(gic_dist_base(d) +
+ GIC_DIST_PRI + (gic_irq(d) * 4 / 4));
+ gicd_pri_reg &= mask;
+ gicd_pri_reg |= 0x80; /* Priority of 0x80 > 0xA0 */
+ writel_relaxed(gicd_pri_reg, gic_dist_base(d) + GIC_DIST_PRI +
+ gic_irq(d) * 4 / 4);
+ mb();
+ raw_spin_unlock(&irq_controller_lock);
+ } else {
+ WARN(1, "Trying to run secure operation from Non-secure mode");
+ }
+}
+
/* before calling this function the interrupts should be disabled
* and the irq must be disabled at gic to avoid spurious interrupts */
bool gic_is_spi_pending(unsigned int irq)
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index eca2ffa..ed6a58c 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -266,9 +266,7 @@
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_PMIC8XXX_PWRKEY=y
# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_HS=y
-# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
CONFIG_SERIAL_MSM_HSL=y
CONFIG_SERIAL_MSM_HSL_CONSOLE=y
CONFIG_DIAG_CHAR=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 18e9085..0bb87fb 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -267,9 +267,7 @@
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_PMIC8XXX_PWRKEY=y
# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_HS=y
-# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
CONFIG_SERIAL_MSM_HSL=y
CONFIG_SERIAL_MSM_HSL_CONSOLE=y
CONFIG_DIAG_CHAR=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index d34f5df..543a4f9f 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -47,12 +47,13 @@
# CONFIG_MSM_SYSMON_COMM is not set
CONFIG_MSM_MODEM_8960=y
CONFIG_MSM_LPASS_8960=y
+CONFIG_MSM_RPM_LOG=y
+CONFIG_MSM_RPM_STATS_LOG=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_BUS_SCALING=y
CONFIG_MSM_BUS_RPM_MULTI_TIER_ENABLED=y
CONFIG_MSM_WATCHDOG=y
CONFIG_MSM_DLOAD_MODE=y
-# CONFIG_MSM_JTAG_V7 is not set
CONFIG_SWP_EMULATE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -73,6 +74,8 @@
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
@@ -83,7 +86,62 @@
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
# CONFIG_INET6_XFRM_MODE_BEET is not set
# CONFIG_IPV6_SIT is not set
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
# CONFIG_ANDROID_PARANOID_NETWORK is not set
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+CONFIG_NETFILTER_NETLINK_QUEUE=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NETFILTER_XT_MARK=y
+CONFIG_NETFILTER_XT_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_IP_SET=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_REJECT_SKERR=y
+CONFIG_IP_NF_TARGET_LOG=y
+CONFIG_IP_NF_TARGET_ULOG=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_MH=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_TARGET_LOG=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
CONFIG_CFG80211=y
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
@@ -137,6 +195,8 @@
CONFIG_SLIMBUS_MSM_CTRL=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+# CONFIG_BATTERY_MSM is not set
CONFIG_SENSORS_PM8XXX_ADC=y
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8960=y
@@ -168,8 +228,6 @@
CONFIG_USB_G_ANDROID=y
CONFIG_RMNET_SMD_CTL_CHANNEL="DATA36_CNTL"
CONFIG_RMNET_SMD_DATA_CHANNEL="DATA36"
-CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
CONFIG_MMC_UNSAFE_RESUME=y
@@ -230,5 +288,3 @@
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
CONFIG_LIBCRC32C=y
-CONFIG_MSM_RPM_LOG=y
-CONFIG_MSM_RPM_STATS_LOG=y
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 8bfbcfa..5bb5139 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -22,6 +22,7 @@
#define GIC_DIST_CTRL 0x000
#define GIC_DIST_CTR 0x004
+#define GIC_DIST_ISR 0x080
#define GIC_DIST_ENABLE_SET 0x100
#define GIC_DIST_ENABLE_CLEAR 0x180
#define GIC_DIST_PENDING_SET 0x200
@@ -49,6 +50,7 @@
void gic_enable_ppi(unsigned int);
bool gic_is_spi_pending(unsigned int irq);
void gic_clear_spi_pending(unsigned int irq);
+void gic_set_irq_secure(unsigned int irq);
static inline void gic_init(unsigned int nr, int start,
void __iomem *dist , void __iomem *cpu)
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/kernel/perf_event_msm.c b/arch/arm/kernel/perf_event_msm.c
index a55ce3f..4a8e276 100644
--- a/arch/arm/kernel/perf_event_msm.c
+++ b/arch/arm/kernel/perf_event_msm.c
@@ -676,7 +676,7 @@
{
int irq = *(unsigned int *)info;
- enable_percpu_irq(irq, 0);
+ enable_percpu_irq(irq, IRQ_TYPE_EDGE_RISING);
}
static void disable_irq_callback(void *info)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 4328ac3..ea64ba6 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -468,9 +468,7 @@
static void ipi_timer(void)
{
struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
- irq_enter();
evt->event_handler(evt);
- irq_exit();
}
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
@@ -624,7 +622,9 @@
/* Wake up from WFI/WFE using SGI */
break;
case IPI_TIMER:
+ irq_enter();
ipi_timer();
+ irq_exit();
break;
case IPI_RESCHEDULE:
@@ -632,15 +632,21 @@
break;
case IPI_CALL_FUNC:
+ irq_enter();
generic_smp_call_function_interrupt();
+ irq_exit();
break;
case IPI_CALL_FUNC_SINGLE:
+ irq_enter();
generic_smp_call_function_single_interrupt();
+ irq_exit();
break;
case IPI_CPU_STOP:
+ irq_enter();
ipi_cpu_stop(cpu);
+ irq_exit();
break;
case IPI_CPU_BACKTRACE:
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 904839b..f087fbc 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -126,6 +126,7 @@
select MSM_SPM_V1
select MSM_SCM if SMP
select MULTI_IRQ_HANDLER
+ select MSM_MULTIMEDIA_USE_ION
select MSM_PM8X60 if PM
config ARCH_MSM8960
@@ -257,6 +258,7 @@
select MSM_RPM_REGULATOR
select MULTI_IRQ_HANDLER
select MSM_PM8X60 if PM
+ select MSM_XO
config ARCH_MSM8625
bool "MSM8625"
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/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 61c742d..e49cd3a 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -463,81 +463,81 @@
static struct acpu_level acpu_freq_tbl_8960_kraitv2_slow[] = {
{ 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 950000 },
{ 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 950000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 975000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 975000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 1000000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 1000000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 1025000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 1025000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1075000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1075000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1100000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1100000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(16), 1125000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1125000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 975000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 975000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 1000000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 1000000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 1025000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 1025000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 1075000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 1075000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1100000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1100000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1125000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1125000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
{ 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1175000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(19), 1200000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(19), 1225000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(19), 1225000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(19), 1237500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(19), 1237500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(19), 1250000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1200000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1225000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1225000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1237500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1237500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1250000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_8960_kraitv2_nom[] = {
{ 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 900000 },
{ 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 900000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 925000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 925000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 950000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 950000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 975000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 975000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 1025000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 1025000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1050000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1050000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(16), 1075000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1075000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1125000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 925000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 925000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 950000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 950000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 975000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 975000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 1025000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 1025000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1050000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1050000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1075000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1075000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1125000 },
{ 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1125000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1150000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(19), 1150000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(19), 1175000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(19), 1175000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(19), 1187500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(19), 1187500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(19), 1200000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1150000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1150000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1175000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1175000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1187500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1187500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1200000 },
{ 0, { 0 } }
};
static struct acpu_level acpu_freq_tbl_8960_kraitv2_fast[] = {
{ 0, { STBY_KHZ, QSB, 0, 0, 0x00 }, L2(0), 850000 },
{ 1, { 384000, PLL_8, 0, 2, 0x00 }, L2(1), 850000 },
- { 1, { 432000, HFPLL, 2, 0, 0x20 }, L2(6), 875000 },
- { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(6), 875000 },
- { 1, { 540000, HFPLL, 2, 0, 0x28 }, L2(6), 900000 },
- { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(6), 900000 },
- { 1, { 648000, HFPLL, 1, 0, 0x18 }, L2(6), 925000 },
- { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(6), 925000 },
- { 1, { 756000, HFPLL, 1, 0, 0x1C }, L2(11), 975000 },
- { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(11), 975000 },
- { 1, { 864000, HFPLL, 1, 0, 0x20 }, L2(11), 1000000 },
- { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(11), 1000000 },
- { 1, { 972000, HFPLL, 1, 0, 0x24 }, L2(16), 1025000 },
- { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1025000 },
- { 1, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1075000 },
+ { 0, { 432000, HFPLL, 2, 0, 0x20 }, L2(7), 875000 },
+ { 1, { 486000, HFPLL, 2, 0, 0x24 }, L2(7), 875000 },
+ { 0, { 540000, HFPLL, 2, 0, 0x28 }, L2(7), 900000 },
+ { 1, { 594000, HFPLL, 1, 0, 0x16 }, L2(7), 900000 },
+ { 0, { 648000, HFPLL, 1, 0, 0x18 }, L2(7), 925000 },
+ { 1, { 702000, HFPLL, 1, 0, 0x1A }, L2(7), 925000 },
+ { 0, { 756000, HFPLL, 1, 0, 0x1C }, L2(7), 975000 },
+ { 1, { 810000, HFPLL, 1, 0, 0x1E }, L2(7), 975000 },
+ { 0, { 864000, HFPLL, 1, 0, 0x20 }, L2(7), 1000000 },
+ { 1, { 918000, HFPLL, 1, 0, 0x22 }, L2(7), 1000000 },
+ { 0, { 972000, HFPLL, 1, 0, 0x24 }, L2(7), 1025000 },
+ { 1, { 1026000, HFPLL, 1, 0, 0x26 }, L2(7), 1025000 },
+ { 0, { 1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1075000 },
{ 1, { 1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1075000 },
- { 1, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1100000 },
- { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(19), 1100000 },
- { 1, { 1296000, HFPLL, 1, 0, 0x30 }, L2(19), 1125000 },
- { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(19), 1125000 },
- { 1, { 1404000, HFPLL, 1, 0, 0x34 }, L2(19), 1137500 },
- { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(19), 1137500 },
- { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(19), 1150000 },
+ { 0, { 1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1100000 },
+ { 1, { 1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1100000 },
+ { 0, { 1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1125000 },
+ { 1, { 1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1125000 },
+ { 0, { 1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1137500 },
+ { 1, { 1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1137500 },
+ { 1, { 1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1150000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index de80a3e..e769566 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -104,6 +104,18 @@
.dir = GPIOMUX_OUT_LOW,
};
+static struct gpiomux_setting gsbi7_func1_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi7_func2_cfg = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
#ifdef CONFIG_USB_EHCI_MSM_HSIC
static struct gpiomux_setting hsic_act_cfg = {
.func = GPIOMUX_FUNC_1,
@@ -199,6 +211,18 @@
[GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
},
},
+ {
+ .gpio = 82, /* GSBI7 UART2 TX */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi7_func2_cfg,
+ },
+ },
+ {
+ .gpio = 83, /* GSBI7 UART2 RX */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi7_func1_cfg,
+ },
+ },
};
static struct msm_gpiomux_config apq8064_slimbus_config[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index a8c5d48..0357c40 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -125,14 +125,14 @@
static struct kgsl_device_platform_data kgsl_3d0_pdata = {
.pwrlevel = {
{
- .gpu_freq = 400000000,
- .bus_freq = 4,
- .io_fraction = 0,
+ .gpu_freq = 192000000,
+ .bus_freq = 2,
+ .io_fraction = 100,
},
{
- .gpu_freq = 320000000,
- .bus_freq = 3,
- .io_fraction = 33,
+ .gpu_freq = 192000000,
+ .bus_freq = 2,
+ .io_fraction = 100,
},
{
.gpu_freq = 1920000000,
@@ -140,8 +140,9 @@
.io_fraction = 100,
},
{
- .gpu_freq = 27000000,
- .bus_freq = 0,
+ .gpu_freq = 192000000,
+ .bus_freq = 2,
+ .io_fraction = 100,
},
},
.init_level = 0,
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index f3eebce..c286c7f 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -97,6 +97,9 @@
};
VREG_CONSUMERS(L23) = {
REGULATOR_SUPPLY("8921_l23", NULL),
+ REGULATOR_SUPPLY("pll_vdd", "pil_qdsp6v4.1"),
+ REGULATOR_SUPPLY("pll_vdd", "pil_qdsp6v4.2"),
+
};
VREG_CONSUMERS(L24) = {
REGULATOR_SUPPLY("8921_l24", NULL),
@@ -106,6 +109,8 @@
REGULATOR_SUPPLY("8921_l25", NULL),
REGULATOR_SUPPLY("VDDD_CDC_D", "tabla-slim"),
REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "tabla-slim"),
+ REGULATOR_SUPPLY("VDDD_CDC_D", "tabla2x-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_A_1P2V", "tabla2x-slim"),
};
VREG_CONSUMERS(L26) = {
REGULATOR_SUPPLY("8921_l26", NULL),
@@ -113,9 +118,11 @@
};
VREG_CONSUMERS(L27) = {
REGULATOR_SUPPLY("8921_l27", NULL),
+ REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.2"),
};
VREG_CONSUMERS(L28) = {
REGULATOR_SUPPLY("8921_l28", NULL),
+ REGULATOR_SUPPLY("core_vdd", "pil_qdsp6v4.1"),
};
VREG_CONSUMERS(S1) = {
REGULATOR_SUPPLY("8921_s1", NULL),
@@ -139,6 +146,10 @@
REGULATOR_SUPPLY("CDC_VDD_CP", "tabla-slim"),
REGULATOR_SUPPLY("CDC_VDDA_TX", "tabla-slim"),
REGULATOR_SUPPLY("CDC_VDDA_RX", "tabla-slim"),
+ REGULATOR_SUPPLY("VDDIO_CDC", "tabla2x-slim"),
+ REGULATOR_SUPPLY("CDC_VDD_CP", "tabla2x-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_TX", "tabla2x-slim"),
+ REGULATOR_SUPPLY("CDC_VDDA_RX", "tabla2x-slim"),
REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
};
VREG_CONSUMERS(S5) = {
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 79b4c07..2618db3 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -384,9 +384,68 @@
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 = {
@@ -605,12 +664,6 @@
msm_mpm_irq_extn_init(data);
gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
(void *)MSM_QGIC_CPU_BASE);
-
- /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
- writel_relaxed(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
-
- writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
- mb();
}
static struct platform_device msm8064_device_saw_regulator_core0 = {
@@ -1135,6 +1188,7 @@
static struct platform_device *cdp_devices[] __initdata = {
&apq8064_device_uart_gsbi1,
+ &apq8064_device_uart_gsbi7,
&msm_device_sps_apq8064,
};
@@ -1277,6 +1331,8 @@
platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
apq8064_init_gpu();
+ platform_add_devices(msm_footswitch_devices,
+ msm_num_footswitch_devices);
}
MACHINE_START(APQ8064_SIM, "QCT APQ8064 SIMULATOR")
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index 30c912e..e0bc723 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -495,6 +495,34 @@
};
#endif
+static struct camera_vreg_t msm_8930_s5k3l1yx_vreg[] = {
+ {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+ {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
+static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
+ .flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_s5k3l1yx = {
+ .mount_angle = 0,
+ .cam_vreg = msm_8930_s5k3l1yx_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8930_s5k3l1yx_vreg),
+ .gpio_conf = &msm_8930_back_cam_gpio_conf,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_s5k3l1yx_data = {
+ .sensor_name = "s5k3l1yx",
+ .pdata = &msm_camera_csi_device_data[0],
+ .flash_data = &flash_s5k3l1yx,
+ .sensor_platform_info = &sensor_board_info_s5k3l1yx,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+};
+
void __init msm8930_init_cam(void)
{
msm_gpiomux_install(msm8930_cam_common_configs,
@@ -527,6 +555,10 @@
I2C_BOARD_INFO("mt9m114", 0x48),
.platform_data = &msm_camera_sensor_mt9m114_data,
},
+ {
+ I2C_BOARD_INFO("s5k3l1yx", 0x20),
+ .platform_data = &msm_camera_sensor_s5k3l1yx_data,
+ },
#ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
{
I2C_BOARD_INFO("sc628a", 0x6E),
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index f55125c..d871e04 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -228,6 +228,11 @@
pr_err("enable l2 failed, rc=%d\n", rc);
return -ENODEV;
}
+ usleep(10000);
+ gpio_set_value(DISP_RST_GPIO, 1);
+ usleep(10);
+ gpio_set_value(DISP_RST_GPIO, 0);
+ usleep(20);
gpio_set_value(DISP_RST_GPIO, 1);
} else {
@@ -486,6 +491,7 @@
.fpga_3d_config_addr = FPGA_3D_GPIO_CONFIG_ADDR,
.fpga_ctrl_mode = FPGA_SPI_INTF,
.phy_ctrl_settings = &dsi_novatek_cmd_mode_phy_db,
+ .dlane_swap = 0x1,
};
static struct platform_device mipi_dsi_novatek_panel_device = {
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index 0208631..2f9fdcd 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -33,6 +33,7 @@
REGULATOR_SUPPLY("mipi_csi_vdd", "4-001a"),
REGULATOR_SUPPLY("mipi_csi_vdd", "4-006c"),
REGULATOR_SUPPLY("mipi_csi_vdd", "4-0048"),
+ REGULATOR_SUPPLY("mipi_csi_vdd", "4-0020"),
};
VREG_CONSUMERS(L3) = {
REGULATOR_SUPPLY("8038_l3", NULL),
@@ -68,6 +69,8 @@
REGULATOR_SUPPLY("cam_vaf", "4-001a"),
REGULATOR_SUPPLY("cam_vaf", "4-006c"),
REGULATOR_SUPPLY("cam_vaf", "4-0048"),
+ REGULATOR_SUPPLY("cam_vana", "4-0020"),
+ REGULATOR_SUPPLY("cam_vaf", "4-0020"),
};
VREG_CONSUMERS(L10) = {
REGULATOR_SUPPLY("8038_l10", NULL),
@@ -88,6 +91,7 @@
REGULATOR_SUPPLY("cam_vdig", "4-001a"),
REGULATOR_SUPPLY("cam_vdig", "4-006c"),
REGULATOR_SUPPLY("cam_vdig", "4-0048"),
+ REGULATOR_SUPPLY("cam_vdig", "4-0020"),
};
VREG_CONSUMERS(L14) = {
REGULATOR_SUPPLY("8038_l14", NULL),
@@ -108,6 +112,7 @@
REGULATOR_SUPPLY("cam_vio", "4-001a"),
REGULATOR_SUPPLY("cam_vio", "4-006c"),
REGULATOR_SUPPLY("cam_vio", "4-0048"),
+ REGULATOR_SUPPLY("cam_vio", "4-0020"),
};
VREG_CONSUMERS(L19) = {
REGULATOR_SUPPLY("8038_l19", NULL),
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 3858e63..90cc3c5 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -40,6 +40,7 @@
#include <linux/ks8851.h>
#include <linux/i2c/isa1200.h>
#include <linux/gpio_keys.h>
+#include <linux/memory.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -429,12 +430,9 @@
if (high - low <= bank_size)
return;
- msm8930_reserve_info.low_unstable_address = low + bank_size;
- /* To avoid overflow of u32 compute max_unstable_size
- * by first subtracting low from mb->start)
- * */
- msm8930_reserve_info.max_unstable_size = (mb->start - low) +
- mb->size - bank_size;
+ msm8930_reserve_info.low_unstable_address = mb->start -
+ MIN_MEMORY_BLOCK_SIZE + mb->size;
+ msm8930_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
msm8930_reserve_info.bank_size = bank_size;
pr_info("low unstable address %lx max size %lx bank size %lx\n",
@@ -902,12 +900,6 @@
msm_mpm_irq_extn_init(data);
gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
(void *)MSM_QGIC_CPU_BASE);
-
- /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
- writel_relaxed(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
-
- writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
- mb();
}
static void __init msm8930_init_buses(void)
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 2995679..6c292a4 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -500,6 +500,34 @@
};
#endif
+static struct camera_vreg_t msm_8960_s5k3l1yx_vreg[] = {
+ {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vio", REG_VS, 0, 0, 0},
+ {"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
+};
+
+static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
+ .flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_s5k3l1yx = {
+ .mount_angle = 0,
+ .cam_vreg = msm_8960_s5k3l1yx_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8960_s5k3l1yx_vreg),
+ .gpio_conf = &msm_8960_back_cam_gpio_conf,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_s5k3l1yx_data = {
+ .sensor_name = "s5k3l1yx",
+ .pdata = &msm_camera_csi_device_data[0],
+ .flash_data = &flash_s5k3l1yx,
+ .sensor_platform_info = &sensor_board_info_s5k3l1yx,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+};
+
static struct pm8xxx_mpp_config_data privacy_light_on_config = {
.type = PM8XXX_MPP_TYPE_SINK,
.level = PM8XXX_MPP_CS_OUT_5MA,
@@ -580,6 +608,10 @@
I2C_BOARD_INFO("mt9m114", 0x48),
.platform_data = &msm_camera_sensor_mt9m114_data,
},
+ {
+ I2C_BOARD_INFO("s5k3l1yx", 0x20),
+ .platform_data = &msm_camera_sensor_s5k3l1yx_data,
+ },
#ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
{
I2C_BOARD_INFO("sc628a", 0x6E),
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index f9bc8fc..c5169a8 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -81,6 +81,8 @@
}
};
+static void set_mdp_clocks_for_liquid_wuxga(void);
+
static int msm_fb_detect_panel(const char *name)
{
if (machine_is_msm8960_liquid()) {
@@ -88,8 +90,10 @@
if (SOCINFO_VERSION_MAJOR(ver) == 3) {
if (!strncmp(name, MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
strnlen(MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
- PANEL_NAME_MAX_LEN)))
+ PANEL_NAME_MAX_LEN))) {
+ set_mdp_clocks_for_liquid_wuxga();
return 0;
+ }
} else {
if (!strncmp(name, MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
strnlen(MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
@@ -643,6 +647,24 @@
#endif
};
+/**
+ * Set MDP clocks to high frequency to avoid DSI underflow
+ * when using high resolution 1200x1920 WUXGA panel.
+ */
+static void set_mdp_clocks_for_liquid_wuxga(void)
+{
+ int i;
+
+ mdp_ui_vectors[0].ab = 2000000000;
+ mdp_ui_vectors[0].ib = 2000000000;
+
+ mdp_pdata.mdp_core_clk_rate = 200000000;
+
+ for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
+ mdp_core_clk_rate_table[i] = 200000000;
+
+}
+
void __init msm8960_mdp_writeback(struct memtype_reserve* reserve_table)
{
mdp_pdata.ov0_wb_size = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
@@ -681,9 +703,11 @@
};
#define FPGA_3D_GPIO_CONFIG_ADDR 0xB5
-static int dsi2lvds_gpio[2] = {
+static int dsi2lvds_gpio[4] = {
0,/* Backlight PWM-ID=0 for PMIC-GPIO#24 */
- 0x1F08 /* DSI2LVDS Bridge GPIO Output, mask=0x1f, out=0x08 */
+ 0x1F08, /* DSI2LVDS Bridge GPIO Output, mask=0x1f, out=0x08 */
+ GPIO_LIQUID_EXPANDER_BASE+6, /* TN Enable */
+ GPIO_LIQUID_EXPANDER_BASE+7, /* TN Mode */
};
static struct msm_panel_common_pdata mipi_dsi2lvds_pdata = {
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 04376bc..0375b84 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-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
@@ -98,6 +98,7 @@
PM8XXX_GPIO_OUTPUT_VIN(21, 1, PM_GPIO_VIN_VPH), /* Backlight Enable */
PM8XXX_GPIO_DISABLE(22), /* Disable NFC */
PM8XXX_GPIO_OUTPUT_FUNC(24, 0, PM_GPIO_FUNC_2), /* Bl: Off, PWM mode */
+ PM8XXX_GPIO_OUTPUT_FUNC(25, 0, PM_GPIO_FUNC_2), /* TN_CLK */
PM8XXX_GPIO_INPUT(26, PM_GPIO_PULL_UP_30), /* SD_CARD_DET_N */
PM8XXX_GPIO_OUTPUT(43, PM_GPIO_PULL_UP_30), /* DISP_RESET_N */
PM8XXX_GPIO_OUTPUT(42, 0), /* USB 5V reg enable */
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index 6819d5d..0f05af5 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -33,6 +33,7 @@
REGULATOR_SUPPLY("mipi_csi_vdd", "4-001a"),
REGULATOR_SUPPLY("mipi_csi_vdd", "4-006c"),
REGULATOR_SUPPLY("mipi_csi_vdd", "4-0048"),
+ REGULATOR_SUPPLY("mipi_csi_vdd", "4-0020"),
};
VREG_CONSUMERS(L3) = {
REGULATOR_SUPPLY("8921_l3", NULL),
@@ -74,12 +75,14 @@
REGULATOR_SUPPLY("cam_vana", "4-001a"),
REGULATOR_SUPPLY("cam_vana", "4-006c"),
REGULATOR_SUPPLY("cam_vana", "4-0048"),
+ REGULATOR_SUPPLY("cam_vana", "4-0020"),
};
VREG_CONSUMERS(L12) = {
REGULATOR_SUPPLY("8921_l12", NULL),
REGULATOR_SUPPLY("cam_vdig", "4-001a"),
REGULATOR_SUPPLY("cam_vdig", "4-006c"),
REGULATOR_SUPPLY("cam_vdig", "4-0048"),
+ REGULATOR_SUPPLY("cam_vdig", "4-0020"),
};
VREG_CONSUMERS(L14) = {
REGULATOR_SUPPLY("8921_l14", NULL),
@@ -93,6 +96,7 @@
REGULATOR_SUPPLY("cam_vaf", "4-001a"),
REGULATOR_SUPPLY("cam_vaf", "4-006c"),
REGULATOR_SUPPLY("cam_vaf", "4-0048"),
+ REGULATOR_SUPPLY("cam_vaf", "4-0020"),
};
VREG_CONSUMERS(L17) = {
REGULATOR_SUPPLY("8921_l17", NULL),
@@ -207,6 +211,7 @@
REGULATOR_SUPPLY("cam_vio", "4-001a"),
REGULATOR_SUPPLY("cam_vio", "4-006c"),
REGULATOR_SUPPLY("cam_vio", "4-0048"),
+ REGULATOR_SUPPLY("cam_vio", "4-0020"),
};
VREG_CONSUMERS(LVS6) = {
REGULATOR_SUPPLY("8921_lvs6", NULL),
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 9985b32..49539ef 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -301,10 +301,6 @@
#endif
}
-static void __init reserve_fmem_memory(void)
-{
-}
-
static int msm8960_paddr_to_memtype(unsigned int paddr)
{
return MEMTYPE_EBI1;
@@ -315,11 +311,13 @@
static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
.permission_type = IPT_TYPE_MM_CARVEOUT,
.align = PAGE_SIZE,
+ .reusable = 1,
};
static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
.permission_type = IPT_TYPE_MFC_SHAREDMEM,
.align = PAGE_SIZE,
+ .reusable = 0,
};
static struct ion_co_heap_pdata co_ion_pdata = {
@@ -411,9 +409,8 @@
.dev = { .platform_data = &fmem_pdata },
};
-static void reserve_ion_memory(void)
+static void __init adjust_mem_for_liquid(void)
{
-#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
unsigned int i;
if (!pmem_param_set && machine_is_msm8960_liquid()) {
@@ -427,12 +424,99 @@
}
}
}
- msm8960_reserve_table[MEMTYPE_EBI1].size += msm_ion_cp_mm_size;
- msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
- msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
- msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
- msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
- msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
+}
+
+static void __init reserve_mem_for_ion(enum ion_memory_types mem_type,
+ unsigned long size)
+{
+ msm8960_reserve_table[mem_type].size += size;
+}
+
+static __init const struct ion_platform_heap *find_ion_heap(int heap_id)
+{
+ unsigned int i;
+ for (i = 0; i < ion_pdata.nr; ++i) {
+ const struct ion_platform_heap *heap = &(ion_pdata.heaps[i]);
+ if (heap->id == heap_id)
+ return (const struct ion_platform_heap *) heap;
+ }
+ return 0;
+}
+
+/**
+ * Reserve memory for ION and calculate amount of reusable memory for fmem.
+ * We only reserve memory for heaps that are not reusable. However, we only
+ * support one reusable heap at the moment so we ignore the reusable flag for
+ * other than the first heap with reusable flag set. Also handle special case
+ * for adjacent heap when the adjacent heap is adjacent to a reusable heap.
+ */
+static void __init reserve_ion_memory(void)
+{
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+ unsigned int i;
+ unsigned int reusable_count = 0;
+
+ adjust_mem_for_liquid();
+ fmem_pdata.size = 0;
+ fmem_pdata.reserved_size = 0;
+
+ /* We only support 1 reusable heap. Check if more than one heap
+ * is specified as reusable and set as non-reusable if found.
+ */
+ for (i = 0; i < ion_pdata.nr; ++i) {
+ const struct ion_platform_heap *heap = &(ion_pdata.heaps[i]);
+
+ if (heap->type == ION_HEAP_TYPE_CP && heap->extra_data) {
+ struct ion_cp_heap_pdata *data = heap->extra_data;
+
+ reusable_count += (data->reusable) ? 1 : 0;
+
+ if (data->reusable && reusable_count > 1) {
+ pr_err("%s: Too many heaps specified as "
+ "reusable. Heap %s was not configured "
+ "as reusable.\n", __func__, heap->name);
+ data->reusable = 0;
+ }
+ }
+ }
+
+ for (i = 0; i < ion_pdata.nr; ++i) {
+ int reusable = 0;
+ int adjacent_heap_id = INVALID_HEAP_ID;
+ int adj_reusable = 0;
+ const struct ion_platform_heap *heap = &(ion_pdata.heaps[i]);
+
+ if (heap->extra_data) {
+ switch (heap->type) {
+ case ION_HEAP_TYPE_CP:
+ reusable = ((struct ion_cp_heap_pdata *)
+ heap->extra_data)->reusable;
+ break;
+ case ION_HEAP_TYPE_CARVEOUT:
+ adjacent_heap_id = ((struct ion_co_heap_pdata *)
+ heap->extra_data)->adjacent_mem_id;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (adjacent_heap_id != INVALID_HEAP_ID) {
+ const struct ion_platform_heap *adj_heap =
+ find_ion_heap(adjacent_heap_id);
+ if (adj_heap) {
+ adj_reusable = ((struct ion_cp_heap_pdata *)
+ adj_heap->extra_data)->reusable;
+ if (adj_reusable)
+ fmem_pdata.reserved_size += heap->size;
+ }
+ }
+
+ if (!reusable && !adj_reusable)
+ reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
+ else
+ fmem_pdata.size += heap->size;
+ }
#endif
}
@@ -446,7 +530,6 @@
size_pmem_devices();
reserve_pmem_memory();
reserve_ion_memory();
- reserve_fmem_memory();
reserve_mdp_memory();
}
@@ -898,12 +981,6 @@
msm_mpm_irq_extn_init(data);
gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
(void *)MSM_QGIC_CPU_BASE);
-
- /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
- writel_relaxed(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
-
- writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
- mb();
}
static void __init msm8960_init_buses(void)
@@ -945,12 +1022,54 @@
0x23, 0x83,/* set source impedance sdjusment */
-1};
+#ifdef CONFIG_MSM_BUS_SCALING
+/* Bandwidth requests (zero) if no vote placed */
+static struct msm_bus_vectors usb_init_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 0,
+ .ib = 0,
+ },
+};
+
+/* Bus bandwidth requests in Bytes/sec */
+static struct msm_bus_vectors usb_max_vectors[] = {
+ {
+ .src = MSM_BUS_MASTER_SPS,
+ .dst = MSM_BUS_SLAVE_EBI_CH0,
+ .ab = 60000000, /* At least 480Mbps on bus. */
+ .ib = 960000000, /* MAX bursts rate */
+ },
+};
+
+static struct msm_bus_paths usb_bus_scale_usecases[] = {
+ {
+ ARRAY_SIZE(usb_init_vectors),
+ usb_init_vectors,
+ },
+ {
+ ARRAY_SIZE(usb_max_vectors),
+ usb_max_vectors,
+ },
+};
+
+static struct msm_bus_scale_pdata usb_bus_scale_pdata = {
+ usb_bus_scale_usecases,
+ ARRAY_SIZE(usb_bus_scale_usecases),
+ .name = "usb",
+};
+#endif
+
static struct msm_otg_platform_data msm_otg_pdata = {
.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,
+#ifdef CONFIG_MSM_BUS_SCALING
+ .bus_scale_table = &usb_bus_scale_pdata,
+#endif
};
#endif
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 84a8a42..1f19bf6 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -31,6 +31,7 @@
#include <mach/gpio.h>
#include <mach/msm_spi.h>
#include <mach/msm_bus_board.h>
+#include <mach/msm_xo.h>
#include "timer.h"
#include "devices.h"
#include "board-9615.h"
@@ -568,6 +569,7 @@
msm9615_i2c_init();
regulator_suppress_info_printing();
platform_device_register(&msm9615_device_rpm_regulator);
+ msm_xo_init();
msm_clock_init(&msm9615_clock_init_data);
msm9615_init_buses();
msm9615_device_qup_spi_gsbi3.dev.platform_data =
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index 1bfb759..b4b0b9a 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -233,12 +233,6 @@
void __init msm_copper_init_irq(void)
{
- /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
- writel_relaxed(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
-
- writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
- mb();
-
of_irq_init(irq_match);
}
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 030c129..15f681d 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -226,6 +226,9 @@
} else if (machine_is_msm7627a_qrd1()) {
if (!strncmp(name, "mipi_video_truly_wvga", 21))
ret = 0;
+ } else if (machine_is_msm7627a_evb()) {
+ if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
+ ret = 0;
}
#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
@@ -303,6 +306,18 @@
}
};
+static struct msm_panel_common_pdata mipi_NT35510_pdata = {
+ .pmic_backlight = NULL,/*mipi_NT35510_set_bl,*/
+};
+
+static struct platform_device mipi_dsi_NT35510_panel_device = {
+ .name = "mipi_NT35510",
+ .id = 0,
+ .dev = {
+ .platform_data = &mipi_NT35510_pdata,
+ }
+};
+
static struct platform_device *msm_fb_devices[] __initdata = {
&msm_fb_device,
&lcdc_toshiba_panel_device,
@@ -317,7 +332,8 @@
};
static struct platform_device *evb_fb_devices[] __initdata = {
-
+ &msm_fb_device,
+ &mipi_dsi_NT35510_panel_device,
};
void __init msm_msm7627a_allocate_memory_regions(void)
@@ -487,12 +503,60 @@
return rc;
}
+#define GPIO_QRD3_LCD_BRDG_RESET_N 85
+#define GPIO_QRD3_LCD_BACKLIGHT_EN 96
+#define GPIO_QRD3_LCD_EXT_2V85_EN 35
+#define GPIO_QRD3_LCD_EXT_1V8_EN 40
+
+static unsigned qrd3_mipi_dsi_gpio[] = {
+ GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
+ GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BRDG_RESET_N */
+ GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
+ GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BACKLIGHT_EN */
+ GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0, GPIO_CFG_OUTPUT,
+ GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_2V85_EN */
+ GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0, GPIO_CFG_OUTPUT,
+ GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_1V8_EN */
+};
+
+static int msm_fb_dsi_client_qrd3_reset(void)
+{
+ int rc = 0;
+
+ rc = gpio_request(GPIO_QRD3_LCD_BRDG_RESET_N, "qrd3_lcd_brdg_reset_n");
+ if (rc < 0) {
+ pr_err("failed to request qrd3 lcd brdg reset_n\n");
+ return rc;
+ }
+
+ rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("Failed to enable LCD Bridge reset enable\n");
+ return rc;
+ }
+
+ rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
+ if (rc < 0) {
+ pr_err("Failed GPIO bridge Reset\n");
+ gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
+ return rc;
+ }
+
+ return rc;
+}
+
static int msm_fb_dsi_client_reset(void)
{
int rc = 0;
if (machine_is_msm7627a_qrd1())
rc = msm_fb_dsi_client_qrd1_reset();
+ else if (machine_is_msm7627a_evb())
+ rc = msm_fb_dsi_client_qrd3_reset();
else
rc = msm_fb_dsi_client_msm_reset();
@@ -650,7 +714,7 @@
gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
- if (!on) {
+ if (on) {
gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
msleep(20);
gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
@@ -662,12 +726,99 @@
return rc;
}
+static int qrd3_dsi_gpio_initialized;
+
+static int mipi_dsi_panel_qrd3_power(int on)
+{
+ int rc = 0;
+
+ if (!qrd3_dsi_gpio_initialized) {
+ rc = gpio_request(GPIO_QRD3_LCD_BACKLIGHT_EN,
+ "qrd3_gpio_bkl_en");
+ if (rc < 0)
+ return rc;
+
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
+ return rc;
+ }
+ rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
+ if (rc < 0) {
+ pr_err("failed to enable backlight\n");
+ gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
+ return rc;
+ }
+
+ rc = gpio_request(GPIO_QRD3_LCD_EXT_2V85_EN,
+ "qrd3_gpio_ext_2v85_en");
+ if (rc < 0)
+ return rc;
+
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_2V85_EN tlmm config\n");
+ return rc;
+ }
+
+ rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_2V85_EN, 1);
+ if (rc < 0) {
+ pr_err("failed to enable external 2V85\n");
+ gpio_free(GPIO_QRD3_LCD_EXT_2V85_EN);
+ return rc;
+ }
+
+ rc = gpio_request(GPIO_QRD3_LCD_EXT_1V8_EN,
+ "qrd3_gpio_ext_1v8_en");
+ if (rc < 0)
+ return rc;
+
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_1V8_EN tlmm config\n");
+ return rc;
+ }
+
+ rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_1V8_EN, 1);
+ if (rc < 0) {
+ pr_err("failed to enable external 1v8\n");
+ gpio_free(GPIO_QRD3_LCD_EXT_1V8_EN);
+ return rc;
+ }
+
+ qrd3_dsi_gpio_initialized = 1;
+ }
+
+ gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, !!on);
+ gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_2V85_EN, !!on);
+ gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_1V8_EN, !!on);
+
+ if (on) {
+ gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
+ msleep(20);
+ gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 0);
+ msleep(20);
+ gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
+ msleep(20);
+ }
+
+ return rc;
+}
+
static int mipi_dsi_panel_power(int on)
{
int rc = 0;
if (machine_is_msm7627a_qrd1())
rc = mipi_dsi_panel_qrd1_power(on);
+ else if (machine_is_msm7627a_evb())
+ rc = mipi_dsi_panel_qrd3_power(on);
else
rc = mipi_dsi_panel_msm_power(on);
return rc;
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index d2add18..0680c44 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gpio_event.h>
+#include <linux/memblock.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
@@ -799,6 +800,11 @@
msm_reserve();
}
+static void __init msm8625_reserve(void)
+{
+ memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
+}
+
static void __init msm_device_i2c_init(void)
{
if (machine_is_msm8625_rumi3()) {
@@ -1239,6 +1245,7 @@
MACHINE_START(MSM8625_RUMI3, "QCT MSM8625 RUMI3")
.boot_params = PHYS_OFFSET + 0x100,
.map_io = msm8625_map_io,
+ .reserve = msm8625_reserve,
.init_irq = msm8625_init_irq,
.init_machine = msm8625_rumi3_init,
.timer = &msm_timer,
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 7653043..8ecfea2 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4846,35 +4846,36 @@
CLK_LOOKUP("pll4", pll4_clk.c, NULL),
CLK_LOOKUP("measure", measure_clk.c, "debug"),
- CLK_DUMMY("bus_clk", AFAB_CLK, "msm_apps_fab", 0),
- CLK_DUMMY("bus_a_clk", AFAB_A_CLK, "msm_apps_fab", 0),
- CLK_DUMMY("bus_clk", SFAB_CLK, "msm_sys_fab", 0),
- CLK_DUMMY("bus_a_clk", SFAB_A_CLK, "msm_sys_fab", 0),
- CLK_DUMMY("bus_clk", SFPB_CLK, "msm_sys_fpb", 0),
- CLK_DUMMY("bus_a_clk", SFPB_A_CLK, "msm_sys_fpb", 0),
- CLK_DUMMY("bus_clk", MMFAB_CLK, "msm_mm_fab", 0),
- CLK_DUMMY("bus_a_clk", MMFAB_A_CLK, "msm_mm_fab", 0),
- CLK_DUMMY("bus_clk", CFPB_CLK, "msm_cpss_fpb", 0),
- CLK_DUMMY("bus_a_clk", CFPB_A_CLK, "msm_cpss_fpb", 0),
- CLK_LOOKUP("mem_clk", ebi1_msmbus_clk.c, "msm_bus"),
- CLK_DUMMY("mem_a_clk", EBI1_A_CLK, "msm_bus", 0),
+ CLK_LOOKUP("bus_clk", afab_clk.c, "msm_apps_fab"),
+ CLK_LOOKUP("bus_a_clk", afab_a_clk.c, "msm_apps_fab"),
+ CLK_LOOKUP("bus_clk", cfpb_clk.c, "msm_cpss_fpb"),
+ CLK_LOOKUP("bus_a_clk", cfpb_a_clk.c, "msm_cpss_fpb"),
+ CLK_LOOKUP("bus_clk", sfab_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_a_clk", sfab_a_clk.c, "msm_sys_fab"),
+ CLK_LOOKUP("bus_clk", sfpb_clk.c, "msm_sys_fpb"),
+ CLK_LOOKUP("bus_a_clk", sfpb_a_clk.c, "msm_sys_fpb"),
+ CLK_LOOKUP("bus_clk", mmfab_clk.c, "msm_mm_fab"),
+ CLK_LOOKUP("bus_a_clk", mmfab_a_clk.c, "msm_mm_fab"),
+ CLK_LOOKUP("mem_clk", ebi1_msmbus_clk.c, "msm_bus"),
+ CLK_LOOKUP("mem_a_clk", ebi1_a_clk.c, "msm_bus"),
- CLK_DUMMY("ebi1_clk", EBI1_CLK, NULL, 0),
- CLK_DUMMY("dfab_clk", DFAB_CLK, NULL, 0),
- CLK_DUMMY("dfab_a_clk", DFAB_A_CLK, NULL, 0),
- CLK_DUMMY("bus_clk", MMFPB_CLK, NULL, 0),
- CLK_DUMMY("bus_a_clk", MMFPB_A_CLK, NULL, 0),
+ CLK_LOOKUP("ebi1_clk", ebi1_clk.c, ""),
+ CLK_LOOKUP("dfab_clk", dfab_clk.c, ""),
+ CLK_LOOKUP("dfab_a_clk", dfab_a_clk.c, ""),
+ CLK_LOOKUP("mmfpb_clk", mmfpb_clk.c, ""),
+ CLK_LOOKUP("mmfpb_a_clk", mmfpb_a_clk.c, "clock-8960"),
+ CLK_LOOKUP("cfpb_a_clk", cfpb_a_clk.c, "clock-8960"),
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, "msm_serial_hsl.0"),
+ CLK_LOOKUP("core_clk", gsbi1_uart_clk.c, "msm_serial_hsl.1"),
CLK_LOOKUP("core_clk", gsbi2_uart_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi3_uart_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi4_uart_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi5_uart_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi6_uart_clk.c, ""),
- CLK_LOOKUP("core_clk", gsbi7_uart_clk.c, ""),
+ CLK_LOOKUP("core_clk", gsbi7_uart_clk.c, "msm_serial_hsl.0"),
CLK_LOOKUP("core_clk", gsbi1_qup_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi2_qup_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi3_qup_clk.c, ""),
@@ -4883,7 +4884,7 @@
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"),
@@ -4908,13 +4909,13 @@
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, "msm_serial_hsl.0"),
+ CLK_LOOKUP("iface_clk", gsbi1_p_clk.c, "msm_serial_hsl.1"),
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, "spi_qsd.0"),
CLK_LOOKUP("iface_clk", gsbi6_p_clk.c, ""),
- CLK_LOOKUP("iface_clk", gsbi7_p_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gsbi7_p_clk.c, "msm_serial_hsl.0"),
CLK_LOOKUP("iface_clk", tsif_p_clk.c, ""),
CLK_LOOKUP("iface_clk", usb_fs1_p_clk.c, ""),
CLK_LOOKUP("iface_clk", usb_hs1_p_clk.c, "msm_otg"),
@@ -5030,6 +5031,7 @@
CLK_LOOKUP("iface_clk", vfe_p_clk.c, "footswitch-8x60.8"),
CLK_LOOKUP("vpe_pclk", vpe_p_clk.c, ""),
CLK_LOOKUP("iface_pclk", vpe_p_clk.c, "footswitch-8x60.9"),
+
CLK_LOOKUP("mi2s_bit_clk", mi2s_bit_clk.c, ""),
CLK_LOOKUP("mi2s_osr_clk", mi2s_osr_clk.c, ""),
CLK_LOOKUP("i2s_mic_bit_clk", codec_i2s_mic_bit_clk.c, ""),
@@ -5042,7 +5044,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, ""),
@@ -5053,16 +5055,19 @@
CLK_LOOKUP("core_clk", vcodec_axi_a_clk.c, ""),
CLK_LOOKUP("core_clk", vcodec_axi_b_clk.c, ""),
CLK_LOOKUP("core_clk", gfx3d_axi_clk.c, ""),
- CLK_DUMMY("dfab_dsps_clk", DFAB_DSPS_CLK, "", 0),
- CLK_DUMMY("core_clk", DFAB_USB_HS_CLK, "msm_otg", 0),
- CLK_DUMMY("core_clk", DFAB_USB_HS3_CLK, "msm_ehci_host.0", 0),
- CLK_DUMMY("core_clk", DFAB_USB_HS4_CLK, "msm_ehci_host.1", 0),
- CLK_DUMMY("bus_clk", DFAB_SDC1_CLK, "", 0),
- CLK_DUMMY("bus_clk", DFAB_SDC2_CLK, "", 0),
- CLK_DUMMY("bus_clk", DFAB_SDC3_CLK, "", 0),
- CLK_DUMMY("bus_clk", DFAB_SDC4_CLK, "", 0),
- CLK_DUMMY("dfab_clk", DFAB_CLK, "", 0),
- CLK_DUMMY("bus_clk", DFAB_SCM_CLK, "scm", 0),
+
+ CLK_LOOKUP("dfab_dsps_clk", dfab_dsps_clk.c, NULL),
+ CLK_LOOKUP("core_clk", dfab_usb_hs_clk.c, "msm_otg"),
+ CLK_LOOKUP("core_clk", dfab_usb_hs3_clk.c, "msm_ehci_host.0"),
+ CLK_LOOKUP("core_clk", dfab_usb_hs3_clk.c, "msm_ehci_host.1"),
+ CLK_LOOKUP("bus_clk", dfab_sdc1_clk.c, "msm_sdcc.1"),
+ CLK_LOOKUP("bus_clk", dfab_sdc2_clk.c, "msm_sdcc.2"),
+ CLK_LOOKUP("bus_clk", dfab_sdc3_clk.c, "msm_sdcc.3"),
+ CLK_LOOKUP("bus_clk", dfab_sdc4_clk.c, "msm_sdcc.4"),
+ CLK_LOOKUP("dfab_clk", dfab_sps_clk.c, "msm_sps"),
+ CLK_LOOKUP("bus_clk", dfab_bam_dmux_clk.c, "BAM_RMNT"),
+ CLK_LOOKUP("bus_clk", dfab_scm_clk.c, "scm"),
+
CLK_LOOKUP("alt_core_clk", usb_hsic_xcvr_fs_clk.c, "msm_hsic_host"),
CLK_LOOKUP("phy_clk", usb_hsic_hsic_clk.c, "msm_hsic_host"),
CLK_LOOKUP("cal_clk", usb_hsic_hsio_cal_clk.c, "msm_hsic_host"),
@@ -5211,6 +5216,7 @@
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-006c"),
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0048"),
CLK_LOOKUP("cam_clk", cam2_clk.c, NULL),
+ CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0020"),
CLK_LOOKUP("csi_src_clk", csi0_src_clk.c, "msm_csid.0"),
CLK_LOOKUP("csi_src_clk", csi1_src_clk.c, "msm_csid.1"),
CLK_LOOKUP("csi_clk", csi0_clk.c, "msm_csid.0"),
@@ -5538,130 +5544,34 @@
* after bootloaders program them.
*/
if (cpu_is_apq8064()) {
- u32 regval, is_pll_enabled;
+ u32 is_pll_enabled;
/* Program pxo_src_clk to source from PXO */
rmwreg(0x1, PXO_SRC_CLK_CTL_REG, 0x7);
- /* Check if PLL8 is active */
- is_pll_enabled = readl_relaxed(BB_PLL8_STATUS_REG) & BIT(16);
- if (!is_pll_enabled) {
- /* Ref clk = 27MHz and program pll8 to 384MHz */
- writel_relaxed(0xE, BB_PLL8_L_VAL_REG);
- writel_relaxed(0x2, BB_PLL8_M_VAL_REG);
- writel_relaxed(0x9, BB_PLL8_N_VAL_REG);
-
- regval = readl_relaxed(BB_PLL8_CONFIG_REG);
-
- /* Enable the main output and the MN accumulator */
- regval |= BIT(23) | BIT(22);
-
- /* Set pre-divider and post-divider values to 1 and 1 */
- regval &= ~BIT(19);
- regval &= ~BM(21, 20);
-
- writel_relaxed(regval, BB_PLL8_CONFIG_REG);
-
- /* Set VCO frequency */
- rmwreg(0x10000, BB_PLL8_CONFIG_REG, 0x30000);
-
- /* Enable AUX output */
- regval = readl_relaxed(BB_PLL8_TEST_CTL_REG);
- regval |= BIT(12);
- writel_relaxed(regval, BB_PLL8_TEST_CTL_REG);
-
- set_fsm_mode(BB_PLL8_MODE_REG);
-
- /* Enable PLL8 by voting from RPM */
- regval = readl_relaxed(BB_PLL_ENA_RPM_REG);
- regval |= BIT(8);
- writel_relaxed(regval, BB_PLL_ENA_RPM_REG);
- }
- /* Check if PLL3 is active */
- is_pll_enabled = readl_relaxed(GPLL1_STATUS_REG) & BIT(16);
- if (!is_pll_enabled) {
- /* Ref clk = 27MHz and program pll3 to 1200MHz */
- writel_relaxed(0x2C, GPLL1_L_VAL_REG);
- writel_relaxed(0x4, GPLL1_M_VAL_REG);
- writel_relaxed(0x9, GPLL1_N_VAL_REG);
-
- regval = readl_relaxed(GPLL1_CONFIG_REG);
-
- /* Set pre-divider and post-divider values to 1 and 1 */
- regval &= ~BIT(15);
- regval |= BIT(16);
-
- writel_relaxed(regval, GPLL1_CONFIG_REG);
-
- /* Set VCO frequency */
- rmwreg(0x180, GPLL1_CONFIG_REG, 0x180);
- }
/* Check if PLL14 is active */
is_pll_enabled = readl_relaxed(BB_PLL14_STATUS_REG) & BIT(16);
if (!is_pll_enabled) {
/* Ref clk = 27MHz and program pll14 to 480MHz */
- writel_relaxed(0x11, BB_PLL14_L_VAL_REG);
+ writel_relaxed(0x00031011, BB_PLL14_L_VAL_REG);
writel_relaxed(0x7, BB_PLL14_M_VAL_REG);
writel_relaxed(0x9, BB_PLL14_N_VAL_REG);
- regval = readl_relaxed(BB_PLL14_CONFIG_REG);
-
- /* Enable the main output and the MN accumulator */
- regval |= BIT(23) | BIT(22);
-
- /* Set pre-divider and post-divider values to 1 and 1 */
- regval &= ~BIT(19);
- regval &= ~BM(21, 20);
-
- writel_relaxed(regval, BB_PLL14_CONFIG_REG);
-
- /* Set VCO frequency */
- rmwreg(0x10000, BB_PLL14_CONFIG_REG, 0x30000);
+ /*
+ * Enable the main output and the MN accumulator
+ * Set pre-divider and post-divider values to 1 and 1
+ */
+ writel_relaxed(0x00C00000, BB_PLL14_CONFIG_REG);
set_fsm_mode(BB_PLL14_MODE_REG);
}
- /* Program PLL2 to 800MHz with ref clk = 27MHz */
- writel_relaxed(0x1D, MM_PLL1_L_VAL_REG);
- writel_relaxed(0x11, MM_PLL1_M_VAL_REG);
- writel_relaxed(0x1B, MM_PLL1_N_VAL_REG);
-
- regval = readl_relaxed(MM_PLL1_CONFIG_REG);
-
- /* Enable the main output and the MN accumulator */
- regval |= BIT(23) | BIT(22);
-
- /* Set pre-divider and post-divider values to 1 and 1 */
- regval &= ~BIT(19);
- regval &= ~BM(21, 20);
-
- writel_relaxed(regval, MM_PLL1_CONFIG_REG);
-
- /* Set VCO frequency */
- rmwreg(0x20000, MM_PLL1_CONFIG_REG, 0x30000);
/* Program PLL15 to 975MHz with ref clk = 27MHz */
- writel_relaxed(0x24, MM_PLL3_L_VAL_REG);
- writel_relaxed(0x1, MM_PLL3_M_VAL_REG);
- writel_relaxed(0x9, MM_PLL3_N_VAL_REG);
+ writel_relaxed(0x31024, MM_PLL3_L_VAL_REG);
+ writel_relaxed(0x1, MM_PLL3_M_VAL_REG);
+ writel_relaxed(0x9, MM_PLL3_N_VAL_REG);
- regval = readl_relaxed(MM_PLL3_CONFIG_REG);
-
- /* Enable the main output and the MN accumulator */
- regval |= BIT(23) | BIT(22);
-
- /* Set pre-divider and post-divider values to 1 and 1 */
- regval &= ~BIT(19);
- regval &= ~BM(21, 20);
-
- writel_relaxed(regval, MM_PLL3_CONFIG_REG);
-
- /* Set VCO frequency */
- rmwreg(0x20000, MM_PLL3_CONFIG_REG, 0x30000);
-
- /* Enable AUX output */
- regval = readl_relaxed(MM_PLL3_TEST_CTL_REG);
- regval |= BIT(12);
- writel_relaxed(regval, MM_PLL3_TEST_CTL_REG);
+ writel_relaxed(0xC20000, MM_PLL3_CONFIG_REG);
/* Check if PLL4 is active */
is_pll_enabled = readl_relaxed(LCC_PLL0_STATUS_REG) & BIT(16);
@@ -5671,18 +5581,7 @@
writel_relaxed(0x27A, LCC_PLL0_M_VAL_REG);
writel_relaxed(0x465, LCC_PLL0_N_VAL_REG);
- regval = readl_relaxed(LCC_PLL0_CONFIG_REG);
-
- /* Enable the main output and the MN accumulator */
- regval |= BIT(23) | BIT(22);
-
- /* Set pre-divider and post-divider values to 1 and 1 */
- regval &= ~BIT(19);
- regval &= ~BM(21, 20);
-
- /* Set VCO frequency */
- regval &= ~BM(17, 16);
- writel_relaxed(regval, LCC_PLL0_CONFIG_REG);
+ writel_relaxed(0xC00000, LCC_PLL0_CONFIG_REG);
set_fsm_mode(LCC_PLL0_MODE_REG);
}
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 92bd59b..f179bdf 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -46,6 +46,7 @@
/* GSBI UART devices */
#define MSM_UART1DM_PHYS (MSM_GSBI1_PHYS + 0x10000)
#define MSM_UART3DM_PHYS (MSM_GSBI3_PHYS + 0x40000)
+#define MSM_UART7DM_PHYS (MSM_GSBI7_PHYS + 0x40000)
/* GSBI QUP devices */
#define MSM_GSBI3_QUP_PHYS (MSM_GSBI3_PHYS + 0x80000)
@@ -127,7 +128,7 @@
struct platform_device apq8064_device_uart_gsbi1 = {
.name = "msm_serial_hsl",
- .id = 0,
+ .id = 1,
.num_resources = ARRAY_SIZE(resources_uart_gsbi1),
.resource = resources_uart_gsbi1,
};
@@ -215,6 +216,33 @@
.resource = resources_qup_spi_gsbi5,
};
+static struct resource resources_uart_gsbi7[] = {
+ {
+ .start = GSBI7_UARTDM_IRQ,
+ .end = GSBI7_UARTDM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART7DM_PHYS,
+ .end = MSM_UART7DM_PHYS + PAGE_SIZE - 1,
+ .name = "uartdm_resource",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MSM_GSBI7_PHYS,
+ .end = MSM_GSBI7_PHYS + PAGE_SIZE - 1,
+ .name = "gsbi_resource",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device apq8064_device_uart_gsbi7 = {
+ .name = "msm_serial_hsl",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_uart_gsbi7),
+ .resource = resources_uart_gsbi7,
+};
+
struct platform_device apq_pcm = {
.name = "msm-pcm-dsp",
.id = -1,
@@ -353,6 +381,7 @@
#define LPASS_SLIMBUS_PHYS 0x28080000
#define LPASS_SLIMBUS_BAM_PHYS 0x28084000
+#define LPASS_SLIMBUS_SLEW (MSM8960_TLMM_PHYS + 0x207C)
/* Board info for the slimbus slave device */
static struct resource slimbus_res[] = {
{
@@ -368,6 +397,12 @@
.name = "slimbus_bam_physical",
},
{
+ .start = LPASS_SLIMBUS_SLEW,
+ .end = LPASS_SLIMBUS_SLEW + 4 - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "slimbus_slew_reg",
+ },
+ {
.start = SLIMBUS0_CORE_EE1_IRQ,
.end = SLIMBUS0_CORE_EE1_IRQ,
.flags = IORESOURCE_IRQ,
@@ -817,6 +852,11 @@
.end = 0x10000000 + SZ_256 - 1,
.flags = IORESOURCE_MEM,
},
+ {
+ .start = 0x10008000,
+ .end = 0x10008000 + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
};
struct platform_device msm_gss = {
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 1f2256f..3944a93 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -1116,12 +1116,6 @@
msm_mpm_irq_extn_init(data);
gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
(void *)MSM_QGIC_CPU_BASE);
-
- /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
- writel_relaxed(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
-
- writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
- mb();
}
struct platform_device msm_bus_9615_sys_fabric = {
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index f3a95a6..31eee43 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -866,6 +866,24 @@
.resource = gsbi0_msm8625_qup_resources,
};
+static struct resource msm8625_gpio_resources[] = {
+ {
+ .start = MSM8625_INT_GPIO_GROUP1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM8625_INT_GPIO_GROUP2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device msm8625_device_gpio = {
+ .name = "msmgpio",
+ .id = -1,
+ .resource = msm8625_gpio_resources,
+ .num_resources = ARRAY_SIZE(msm8625_gpio_resources),
+};
+
static struct clk_lookup msm_clock_8625_dummy[] = {
CLK_DUMMY("core_clk", adm_clk.c, "msm_dmov", 0),
CLK_DUMMY("adsp_clk", adsp_clk.c, NULL, 0),
@@ -987,13 +1005,6 @@
{
gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
(void *)MSM_QGIC_CPU_BASE);
-
- /* Edge trigger PPIs
- */
- writel_relaxed(0x555555F5, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
-
- writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
- mb();
}
void __init msm8625_map_io(void)
@@ -1007,7 +1018,10 @@
static int msm7627a_init_gpio(void)
{
- platform_device_register(&msm_device_gpio);
+ if (cpu_is_msm8625())
+ platform_device_register(&msm8625_device_gpio);
+ else
+ platform_device_register(&msm_device_gpio);
return 0;
}
postcore_initcall(msm7627a_init_gpio);
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index db656f3..fc732da 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -581,9 +581,67 @@
},
};
+static struct resource smd_resource[] = {
+ {
+ .name = "a9_m2a_0",
+ .start = INT_A9_M2A_0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "a9_m2a_5",
+ .start = INT_A9_M2A_5,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "adsp_a11_smsm",
+ .start = INT_ADSP_A11,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smd_subsystem_config smd_config_list[] = {
+ {
+ .irq_config_id = SMD_MODEM,
+ .subsys_name = "modem",
+ .edge = SMD_APPS_MODEM,
+
+ .smd_int.irq_name = "a9_m2a_0",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+
+ .smd_int.out_bit_pos = 1 << 0,
+ .smd_int.out_base = (void __iomem *)MSM_GCC_BASE,
+ .smd_int.out_offset = 0x8,
+
+ .smsm_int.irq_name = "a9_m2a_5",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smd_dev",
+ .smsm_int.dev_id = 0,
+
+ .smsm_int.out_bit_pos = 1 << 5,
+ .smsm_int.out_base = (void __iomem *)MSM_GCC_BASE,
+ .smsm_int.out_offset = 0x8,
+
+ }
+};
+
+static struct smd_platform smd_platform_data = {
+ .num_ss_configs = ARRAY_SIZE(smd_config_list),
+ .smd_ss_configs = smd_config_list,
+};
+
struct platform_device msm_device_smd = {
.name = "msm_smd",
.id = -1,
+ .resource = smd_resource,
+ .num_resources = ARRAY_SIZE(smd_resource),
+ .dev = {
+ .platform_data = &smd_platform_data,
+ }
+
};
static struct resource msm_dmov_resource[] = {
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index a433a89..4670ce8 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -179,9 +179,6 @@
msm_mpm_irq_extn_init(data);
gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, (void *)MSM_QGIC_CPU_BASE);
-
- /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
- writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
}
#define MSM_LPASS_QDSP6SS_PHYS 0x28800000
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 9469de8..e3c875b 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -69,6 +69,7 @@
extern struct platform_device apq8064_device_uart_gsbi1;
extern struct platform_device apq8064_device_uart_gsbi3;
+extern struct platform_device apq8064_device_uart_gsbi7;
extern struct platform_device apq8064_device_qup_i2c_gsbi4;
extern struct platform_device apq8064_device_qup_spi_gsbi5;
extern struct platform_device apq8064_slim_ctrl;
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index c7ef271..6eceea7 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -396,6 +396,7 @@
int fpga_3d_config_addr;
int *gpio;
struct mipi_dsi_phy_ctrl *phy_ctrl_settings;
+ char dlane_swap;
};
struct msm_fb_platform_data {
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index bb33289..06d214f 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -213,6 +213,7 @@
#define CSI_DECODE_6BIT 0
#define CSI_DECODE_8BIT 1
#define CSI_DECODE_10BIT 2
+#define CSI_DECODE_DPCM_10_8_10 5
struct msm_vfe_phy_info {
uint32_t sbuf_phy;
diff --git a/arch/arm/mach-msm/include/mach/msm_bus_board.h b/arch/arm/mach-msm/include/mach/msm_bus_board.h
index 1a87d9c..fd61c98 100644
--- a/arch/arm/mach-msm/include/mach/msm_bus_board.h
+++ b/arch/arm/mach-msm/include/mach/msm_bus_board.h
@@ -205,7 +205,7 @@
MSM_BUS_MASTER_GRAPHICS_3D_PORT1,
MSM_BUS_MASTER_VIDEO_ENC,
MSM_BUS_MASTER_VIDEO_DEC,
- MSM_BUS_MASTER_LAST = MSM_BUS_MMSS_MASTER_UNUSED_2,
+ MSM_BUS_MASTER_LAST = MSM_BUS_MASTER_VIDEO_DEC,
MSM_BUS_SYSTEM_FPB_MASTER_SYSTEM =
MSM_BUS_SYSTEM_MASTER_SYSTEM_FPB,
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index ca8daaa..bb2b019 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -95,6 +95,7 @@
#define MSM_STRONGLY_ORDERED_PAGE 0xFA0F0000
+#define MSM8625_SECONDARY_PHYS 0x0FE00000
#if defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_MSM7X27)
#define MSM_SHARED_RAM_SIZE SZ_1M
diff --git a/arch/arm/mach-msm/include/mach/msm_rtb.h b/arch/arm/mach-msm/include/mach/msm_rtb.h
index 2831428..ac45cbd 100644
--- a/arch/arm/mach-msm/include/mach/msm_rtb.h
+++ b/arch/arm/mach-msm/include/mach/msm_rtb.h
@@ -17,6 +17,7 @@
LOGK_NONE = 0,
LOGK_READL,
LOGK_WRITEL,
+ LOGK_LOGBUF,
LOGK_OTHER,
};
@@ -32,6 +33,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 +57,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/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
index af47425..4be6d9ea 100644
--- a/arch/arm/mach-msm/include/mach/msm_smd.h
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -1,7 +1,7 @@
/* linux/include/asm-arm/arch-msm/msm_smd.h
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -18,6 +18,9 @@
#ifndef __ASM_ARCH_MSM_SMD_H
#define __ASM_ARCH_MSM_SMD_H
+#include <linux/io.h>
+#include <mach/msm_smsm.h>
+
typedef struct smd_channel smd_channel_t;
#define SMD_MAX_CH_NAME_LEN 20 /* includes null char at end */
@@ -28,6 +31,24 @@
#define SMD_EVENT_STATUS 4
#define SMD_EVENT_REOPEN_READY 5
+/*
+ * SMD Processor ID's.
+ *
+ * For all processors that have both SMSM and SMD clients,
+ * the SMSM Processor ID and the SMD Processor ID will
+ * be the same. In cases where a processor only supports
+ * SMD, the entry will only exist in this enum.
+ */
+enum {
+ SMD_APPS = SMSM_APPS,
+ SMD_MODEM = SMSM_MODEM,
+ SMD_Q6 = SMSM_Q6,
+ SMD_WCNSS = SMSM_WCNSS,
+ SMD_DSPS = SMSM_DSPS,
+ SMD_MODEM_Q6_FW,
+ NUM_SMD_SUBSYSTEMS,
+};
+
enum {
SMD_APPS_MODEM = 0,
SMD_APPS_QDSP,
@@ -49,6 +70,59 @@
};
+/*
+ * SMD IRQ Configuration
+ *
+ * Used to initialize IRQ configurations from platform data
+ *
+ * @irq_name: irq_name to query platform data
+ * @irq_id: initialized to -1 in platform data, stores actual irq id on
+ * successful registration
+ * @out_base: if not null then settings used for outgoing interrupt
+ * initialied from platform data
+ */
+
+struct smd_irq_config {
+ /* incoming interrupt config */
+ const char *irq_name;
+ unsigned long flags;
+ int irq_id;
+ const char *device_name;
+ const void *dev_id;
+
+ /* outgoing interrupt config */
+ uint32_t out_bit_pos;
+ void __iomem *out_base;
+ uint32_t out_offset;
+};
+
+/*
+ * SMD subsystem configurations
+ *
+ * SMD subsystems configurations for platform data. This contains the
+ * M2A and A2M interrupt configurations for both SMD and SMSM per
+ * subsystem.
+ *
+ * @subsys_name: name of subsystem passed to PIL
+ * @irq_config_id: unique id for each subsystem
+ * @edge: maps to actual remote subsystem edge
+ *
+ */
+struct smd_subsystem_config {
+ unsigned irq_config_id;
+ const char *subsys_name;
+ int edge;
+
+ struct smd_irq_config smd_int;
+ struct smd_irq_config smsm_int;
+
+};
+
+struct smd_platform {
+ uint32_t num_ss_configs;
+ struct smd_subsystem_config *smd_ss_configs;
+};
+
#ifdef CONFIG_MSM_SMD
/* warning: notify() may be called before open returns */
int smd_open(const char *name, smd_channel_t **ch, void *priv,
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/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index 600a2e9..c856455 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -43,123 +43,10 @@
char *name;
int domain;
} msm_iommu_ctx_names[] = {
- /* Camera */
- {
- .name = "vpe_src",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "vpe_dst",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "vfe_imgwr",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "vfe_misc",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "ijpeg_src",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "ijpeg_dst",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "jpegd_src",
- .domain = GLOBAL_DOMAIN,
- },
- /* Camera */
- {
- .name = "jpegd_dst",
- .domain = GLOBAL_DOMAIN,
- },
- /* Display */
- {
- .name = "mdp_vg1",
- .domain = GLOBAL_DOMAIN,
- },
- /* Display */
- {
- .name = "mdp_vg2",
- .domain = GLOBAL_DOMAIN,
- },
- /* Display */
- {
- .name = "mdp_rgb1",
- .domain = GLOBAL_DOMAIN,
- },
- /* Display */
- {
- .name = "mdp_rgb2",
- .domain = GLOBAL_DOMAIN,
- },
- /* Rotator */
- {
- .name = "rot_src",
- .domain = GLOBAL_DOMAIN,
- },
- /* Rotator */
- {
- .name = "rot_dst",
- .domain = GLOBAL_DOMAIN,
- },
- /* Video */
- {
- .name = "vcodec_a_mm1",
- .domain = GLOBAL_DOMAIN,
- },
- /* Video */
- {
- .name = "vcodec_b_mm2",
- .domain = GLOBAL_DOMAIN,
- },
- /* Video */
- {
- .name = "vcodec_a_stream",
- .domain = GLOBAL_DOMAIN,
- },
-};
-
-static struct mem_pool global_pools[] = {
- [VIDEO_FIRMWARE_POOL] =
- /* Low addresses, intended for video firmware */
- {
- .paddr = SZ_128K,
- .size = SZ_16M - SZ_128K,
- },
- [LOW_256MB_POOL] =
- /*
- * Video can only access first 256MB of memory
- * dedicated pool for such allocations
- */
- {
- .paddr = SZ_16M,
- .size = SZ_256M - SZ_16M,
- },
- [HIGH_POOL] =
- /* Remaining address space up to 2G */
- {
- .paddr = SZ_256M,
- .size = SZ_2G - SZ_256M,
- }
};
static struct msm_iommu_domain msm_iommu_domains[] = {
- [GLOBAL_DOMAIN] = {
- .iova_pools = global_pools,
- .npools = ARRAY_SIZE(global_pools),
- }
};
int msm_iommu_map_extra(struct iommu_domain *domain,
@@ -281,10 +168,8 @@
int msm_use_iommu()
{
- /*
- * For now, just detect if the iommu is attached.
- */
- return iommu_found();
+ /* Kill use of the iommu by these clients for now. */
+ return 0;
}
static int __init msm_subsystem_iommu_init(void)
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index 4b0d26a..6e8c99e 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -53,7 +53,7 @@
/* Load GNSS for Standalone 8064 but not for Fusion 3 */
if (cpu_is_apq8064()) {
if (socinfo_get_platform_subtype() == 0x0)
- pil = pil_get("gnss");
+ pil = pil_get("gss");
} else {
pil = pil_get("modem");
}
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index b672957..7445a61 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -455,6 +455,11 @@
mdm_drv->mdm_status_irq = irq;
status_err:
+ /* Perform early powerup of the external modem in order to
+ * allow tabla devices to be found.
+ */
+ mdm_drv->ops->power_on_mdm_cb(mdm_drv);
+
pr_info("%s: Registering mdm modem\n", __func__);
return misc_register(&mdm_modem_misc);
diff --git a/arch/arm/mach-msm/msm_rtb.c b/arch/arm/mach-msm/msm_rtb.c
index d765f6a..f93a79b 100644
--- a/arch/arm/mach-msm/msm_rtb.c
+++ b/arch/arm/mach-msm/msm_rtb.c
@@ -65,6 +65,7 @@
struct msm_rtb_state msm_rtb = {
.size = SZ_1M,
+ .filter = 1 << LOGK_LOGBUF,
};
module_param_named(filter, msm_rtb.filter, uint, 0644);
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index 5877fbf..4303f83 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, 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
@@ -354,7 +354,7 @@
return ret;
}
- enable_percpu_irq(WDT0_ACCSCSSNBARK_INT, 0);
+ enable_percpu_irq(WDT0_ACCSCSSNBARK_INT, IRQ_TYPE_EDGE_RISING);
/*
* This is only temporary till SBLs turn on the XPUs
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index af272af..74c64c1 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -115,7 +115,7 @@
static int msm_xo_update_vote(struct msm_xo *xo)
{
int ret;
- unsigned vote, prev_vote = xo->mode;
+ unsigned vote, prev_vote = xo->mode, ctx_set;
struct msm_rpm_iv_pair cmd;
if (xo->votes[MSM_XO_MODE_ON])
@@ -141,7 +141,11 @@
} else if (xo == &msm_xo_sources[MSM_XO_CXO]) {
cmd.id = MSM_RPM_ID_CXO_CLK;
cmd.value = msm_xo_sources[MSM_XO_CXO].mode ? 1 : 0;
- ret = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &cmd, 1);
+ if (cpu_is_msm9615())
+ ctx_set = MSM_RPM_CTX_SET_SLEEP;
+ else
+ ctx_set = MSM_RPM_CTX_SET_0;
+ ret = msm_rpmrs_set_noirq(ctx_set, &cmd, 1);
} else {
cmd.id = MSM_RPM_ID_CXO_BUFFERS;
cmd.value = (msm_xo_sources[MSM_XO_TCXO_D0].mode << 0) |
@@ -235,10 +239,9 @@
/*
* TODO: Remove early return for 8064 once RPM XO voting support
- * is available. Remove early return for 8960 CXO once all voters
- * for it are in place.
+ * is available.
*/
- if (cpu_is_apq8064() || (cpu_is_msm8960() && xo_id == MSM_XO_CXO))
+ if (cpu_is_apq8064())
return NULL;
if (xo_id >= NUM_MSM_XO_IDS) {
@@ -304,12 +307,25 @@
int __init msm_xo_init(void)
{
int i;
- int ret;
+ int ret = 0;
struct msm_rpm_iv_pair cmd[2];
for (i = 0; i < ARRAY_SIZE(msm_xo_sources); i++)
INIT_LIST_HEAD(&msm_xo_sources[i].voters);
+ if (cpu_is_msm9615()) {
+ cmd[0].id = MSM_RPM_ID_CXO_CLK;
+ cmd[0].value = 1;
+ ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, cmd, 1);
+ if (ret)
+ goto out;
+
+ cmd[0].id = MSM_RPM_ID_CXO_CLK;
+ cmd[0].value = 0;
+ ret = msm_rpmrs_set(MSM_RPM_CTX_SET_SLEEP, cmd, 1);
+ goto out;
+ }
+
cmd[0].id = MSM_RPM_ID_PXO_CLK;
cmd[0].value = 1;
cmd[1].id = MSM_RPM_ID_CXO_BUFFERS;
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
index 4c94b83..f3e83d9 100644
--- a/arch/arm/mach-msm/pil-gss.c
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -21,6 +21,7 @@
#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>
@@ -34,6 +35,7 @@
#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)
@@ -63,6 +65,7 @@
struct gss_data {
void __iomem *base;
+ void __iomem *qgic2_base;
unsigned long start_addr;
struct delayed_work work;
struct clk *xo;
@@ -139,38 +142,15 @@
writel_relaxed(A5_RESET, base + GSS_CSR_RESET);
}
-static int pil_gss_reset(struct pil_desc *pil)
+static void setup_qgic2_bus_access(void *data)
{
- struct gss_data *drv = dev_get_drvdata(pil->dev);
+ struct gss_data *drv = data;
void __iomem *base = drv->base;
- unsigned long start_addr = drv->start_addr;
- int ret;
+ int i;
- 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();
-
- /* Release A5 from reset. */
- writel_relaxed(0x0, base + GSS_CSR_RESET);
-
- return 0;
+ 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)
@@ -225,6 +205,51 @@
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,
@@ -313,6 +338,15 @@
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);
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index 3c422009..6b48d57 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -198,14 +198,5 @@
trace_hardirqs_off();
- /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
- writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
-
- /* RUMI does not adhere to GIC spec by enabling STIs by default.
- * Enable/clear is supposed to be RO for STIs, but is RW on RUMI.
- */
- if (!machine_is_msm8x60_sim())
- writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
-
gic_secondary_init(0);
}
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/rpm.c b/arch/arm/mach-msm/rpm.c
index fb9d295..05b2953 100644
--- a/arch/arm/mach-msm/rpm.c
+++ b/arch/arm/mach-msm/rpm.c
@@ -31,7 +31,6 @@
#include <asm/hardware/gic.h>
#include <mach/msm_iomap.h>
#include <mach/rpm.h>
-#include <mach/socinfo.h>
/******************************************************************************
* Data type and structure definitions
@@ -425,9 +424,6 @@
uint32_t sel_masks[SEL_MASK_SIZE] = {};
int rc;
- if (cpu_is_apq8064())
- return 0;
-
if (ctx >= MSM_RPM_CTX_SET_COUNT) {
rc = -EINVAL;
goto set_common_exit;
@@ -471,9 +467,6 @@
int rc;
int i;
- if (cpu_is_apq8064())
- return 0;
-
if (ctx >= MSM_RPM_CTX_SET_COUNT) {
rc = -EINVAL;
goto clear_common_exit;
@@ -612,9 +605,6 @@
int rc;
int i;
- if (cpu_is_apq8064())
- return 0;
-
seq_begin = msm_rpm_read(MSM_RPM_PAGE_STATUS,
target_status(MSM_RPM_STATUS_ID_SEQUENCE));
@@ -768,9 +758,6 @@
int rc;
int i;
- if (cpu_is_apq8064())
- return 0;
-
INIT_LIST_HEAD(&n->list);
rc = msm_rpm_fill_sel_masks(n->sel_masks, req, count);
if (rc)
@@ -823,9 +810,6 @@
int rc;
int i;
- if (cpu_is_apq8064())
- return 0;
-
rc = mutex_lock_interruptible(&msm_rpm_mutex);
if (rc)
goto unregister_notification_exit;
@@ -951,9 +935,6 @@
unsigned int irq;
int rc;
- if (cpu_is_apq8064())
- return 0;
-
memcpy(&msm_rpm_data, data, sizeof(struct msm_rpm_platform_data));
msm_rpm_sel_mask_size = msm_rpm_data.sel_last / 32 + 1;
BUG_ON(SEL_MASK_SIZE < msm_rpm_sel_mask_size);
diff --git a/arch/arm/mach-msm/rpm_resources.c b/arch/arm/mach-msm/rpm_resources.c
index 609528c..546a917 100644
--- a/arch/arm/mach-msm/rpm_resources.c
+++ b/arch/arm/mach-msm/rpm_resources.c
@@ -1016,12 +1016,13 @@
/* Initialize listed bitmap for valid resource IDs */
for (i = 0; i < ARRAY_SIZE(msm_rpmrs_resources); i++) {
- for (k = 0; k < msm_rpmrs_resources[i]->size; k++)
+ for (k = 0; k < msm_rpmrs_resources[i]->size; k++) {
if (msm_rpmrs_resources[i]->rs[k].id >=
MSM_RPM_ID_LAST)
continue;
set_bit(msm_rpmrs_resources[i]->rs[k].id,
msm_rpmrs_listed);
+ }
}
return 0;
@@ -1032,9 +1033,6 @@
struct msm_rpm_iv_pair req;
int rc;
- if (cpu_is_apq8064())
- return -ENODEV;
-
BUG_ON(!msm_rpmrs_levels);
if (cpu_is_msm8x60()) {
@@ -1068,7 +1066,7 @@
static int __init msm_rpmrs_l2_init(void)
{
- if (cpu_is_msm8960() || cpu_is_msm8930()) {
+ if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_apq8064()) {
msm_pm_set_l2_flush_flag(0);
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 10593c6..b95c3aa 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -102,6 +102,45 @@
uint32_t last_value;
};
+struct interrupt_config_item {
+ /* must be initialized */
+ irqreturn_t (*irq_handler)(int req, void *data);
+ /* outgoing interrupt config (set from platform data) */
+ uint32_t out_bit_pos;
+ void __iomem *out_base;
+ uint32_t out_offset;
+};
+
+struct interrupt_config {
+ struct interrupt_config_item smd;
+ struct interrupt_config_item smsm;
+};
+
+static irqreturn_t smd_modem_irq_handler(int irq, void *data);
+static irqreturn_t smd_dsp_irq_handler(int irq, void *data);
+static irqreturn_t smd_dsps_irq_handler(int irq, void *data);
+static irqreturn_t smd_wcnss_irq_handler(int irq, void *data);
+static irqreturn_t smsm_irq_handler(int irq, void *data);
+
+static struct interrupt_config private_intr_config[NUM_SMD_SUBSYSTEMS] = {
+ [SMD_MODEM] = {
+ .smd.irq_handler = smd_modem_irq_handler,
+ .smsm.irq_handler = smsm_irq_handler,
+ },
+ [SMD_Q6] = {
+ .smd.irq_handler = smd_dsp_irq_handler,
+ .smsm.irq_handler = smsm_irq_handler,
+ },
+ [SMD_DSPS] = {
+ .smd.irq_handler = smd_dsps_irq_handler,
+ .smsm.irq_handler = smsm_irq_handler,
+ },
+ [SMD_WCNSS] = {
+ .smd.irq_handler = smd_wcnss_irq_handler,
+ .smsm.irq_handler = smsm_irq_handler,
+ },
+};
+
#define SMSM_STATE_ADDR(entry) (smsm_info.state + entry)
#define SMSM_INTR_MASK_ADDR(entry, host) (smsm_info.intr_mask + \
entry * SMSM_NUM_HOSTS + host)
@@ -240,7 +279,6 @@
static remote_spinlock_t remote_spinlock;
static LIST_HEAD(smd_ch_list_loopback);
-static irqreturn_t smsm_irq_handler(int irq, void *data);
static void smd_fake_irq_handler(unsigned long arg);
static void smsm_cb_snapshot(void);
@@ -275,6 +313,98 @@
static inline void wakeup_v1_riva(void) {}
#endif
+static inline void notify_modem_smd(void)
+{
+ static const struct interrupt_config_item *intr
+ = &private_intr_config[SMD_MODEM].smd;
+ if (intr->out_base)
+ smd_write_intr(intr->out_bit_pos,
+ intr->out_base + intr->out_offset);
+ else
+ MSM_TRIG_A2M_SMD_INT;
+}
+
+static inline void notify_dsp_smd(void)
+{
+ static const struct interrupt_config_item *intr
+ = &private_intr_config[SMD_Q6].smd;
+ if (intr->out_base)
+ smd_write_intr(intr->out_bit_pos,
+ intr->out_base + intr->out_offset);
+ else
+ MSM_TRIG_A2Q6_SMD_INT;
+}
+
+static inline void notify_dsps_smd(void)
+{
+ static const struct interrupt_config_item *intr
+ = &private_intr_config[SMD_DSPS].smd;
+ if (intr->out_base)
+ smd_write_intr(intr->out_bit_pos,
+ intr->out_base + intr->out_offset);
+ else
+ MSM_TRIG_A2DSPS_SMD_INT;
+}
+
+static inline void notify_wcnss_smd(void)
+{
+ static const struct interrupt_config_item *intr
+ = &private_intr_config[SMD_WCNSS].smd;
+ wakeup_v1_riva();
+
+ if (intr->out_base)
+ smd_write_intr(intr->out_bit_pos,
+ intr->out_base + intr->out_offset);
+ else
+ MSM_TRIG_A2WCNSS_SMD_INT;
+}
+
+static inline void notify_modem_smsm(void)
+{
+ static const struct interrupt_config_item *intr
+ = &private_intr_config[SMD_MODEM].smsm;
+ if (intr->out_base)
+ smd_write_intr(intr->out_bit_pos,
+ intr->out_base + intr->out_offset);
+ else
+ MSM_TRIG_A2M_SMSM_INT;
+}
+
+static inline void notify_dsp_smsm(void)
+{
+ static const struct interrupt_config_item *intr
+ = &private_intr_config[SMD_Q6].smsm;
+ if (intr->out_base)
+ smd_write_intr(intr->out_bit_pos,
+ intr->out_base + intr->out_offset);
+ else
+ MSM_TRIG_A2Q6_SMSM_INT;
+}
+
+static inline void notify_dsps_smsm(void)
+{
+ static const struct interrupt_config_item *intr
+ = &private_intr_config[SMD_DSPS].smsm;
+ if (intr->out_base)
+ smd_write_intr(intr->out_bit_pos,
+ intr->out_base + intr->out_offset);
+ else
+ MSM_TRIG_A2DSPS_SMSM_INT;
+}
+
+static inline void notify_wcnss_smsm(void)
+{
+ static const struct interrupt_config_item *intr
+ = &private_intr_config[SMD_WCNSS].smsm;
+ wakeup_v1_riva();
+
+ if (intr->out_base)
+ smd_write_intr(intr->out_bit_pos,
+ intr->out_base + intr->out_offset);
+ else
+ MSM_TRIG_A2WCNSS_SMSM_INT;
+}
+
static void notify_other_smsm(uint32_t smsm_entry, uint32_t notify_mask)
{
/* older protocol don't use smsm_intr_mask,
@@ -282,7 +412,7 @@
if (!smsm_info.intr_mask ||
(__raw_readl(SMSM_INTR_MASK_ADDR(smsm_entry, SMSM_MODEM))
& notify_mask))
- MSM_TRIG_A2M_SMSM_INT;
+ notify_modem_smsm();
if (smsm_info.intr_mask &&
(__raw_readl(SMSM_INTR_MASK_ADDR(smsm_entry, SMSM_Q6))
@@ -296,46 +426,24 @@
__raw_writel(mux_val,
SMSM_INTR_MUX_ADDR(SMEM_APPS_Q6_SMSM));
}
- MSM_TRIG_A2Q6_SMSM_INT;
+ notify_dsp_smsm();
}
if (smsm_info.intr_mask &&
(__raw_readl(SMSM_INTR_MASK_ADDR(smsm_entry, SMSM_WCNSS))
& notify_mask)) {
- wakeup_v1_riva();
- MSM_TRIG_A2WCNSS_SMSM_INT;
+ notify_wcnss_smsm();
}
if (smsm_info.intr_mask &&
(__raw_readl(SMSM_INTR_MASK_ADDR(smsm_entry, SMSM_DSPS))
& notify_mask)) {
- MSM_TRIG_A2DSPS_SMSM_INT;
+ notify_dsps_smsm();
}
smsm_cb_snapshot();
}
-static inline void notify_modem_smd(void)
-{
- MSM_TRIG_A2M_SMD_INT;
-}
-
-static inline void notify_dsp_smd(void)
-{
- MSM_TRIG_A2Q6_SMD_INT;
-}
-
-static inline void notify_dsps_smd(void)
-{
- MSM_TRIG_A2DSPS_SMD_INT;
-}
-
-static inline void notify_wcnss_smd(void)
-{
- wakeup_v1_riva();
- MSM_TRIG_A2WCNSS_SMD_INT;
-}
-
void smd_diag(void)
{
char *x;
@@ -451,23 +559,6 @@
uint32_t remote_pid;
};
-/*
- * SMD Processor ID's.
- *
- * For all processors that have both SMSM and SMD clients,
- * the SMSM Processor ID and the SMD Processor ID will
- * be the same. In cases where a processor only supports
- * SMD, the entry will only exist in this enum.
- */
-enum {
- SMD_APPS = SMSM_APPS,
- SMD_MODEM = SMSM_MODEM,
- SMD_Q6 = SMSM_Q6,
- SMD_WCNSS = SMSM_WCNSS,
- SMD_DSPS = SMSM_DSPS,
- SMD_MODEM_Q6_FW,
-};
-
/**
* Maps edge type to local and remote processor ID's.
*/
@@ -1008,32 +1099,26 @@
return IRQ_HANDLED;
}
-#if defined(CONFIG_QDSP6)
static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
{
handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
}
-#endif
-#if defined(CONFIG_DSPS)
static irqreturn_t smd_dsps_irq_handler(int irq, void *data)
{
handle_smd_irq(&smd_ch_list_dsps, notify_dsps_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
}
-#endif
-#if defined(CONFIG_WCNSS)
static irqreturn_t smd_wcnss_irq_handler(int irq, void *data)
{
handle_smd_irq(&smd_ch_list_wcnss, notify_wcnss_smd);
handle_smd_irq_closing_list();
return IRQ_HANDLED;
}
-#endif
static void smd_fake_irq_handler(unsigned long arg)
{
@@ -2567,22 +2652,121 @@
pr_err("smd_core_init: "
"enable_irq_wake failed for INT_DSPS_A11_SMSM\n");
#endif
-
- /* we may have missed a signal while booting -- fake
- * an interrupt to make sure we process any existing
- * state
- */
- smsm_irq_handler(0, 0);
-
SMD_INFO("smd_core_init() done\n");
return 0;
}
+static int intr_init(struct interrupt_config_item *private_irq,
+ struct smd_irq_config *platform_irq,
+ struct platform_device *pdev
+ )
+{
+ int irq_id;
+ int ret;
+ int ret_wake;
+
+ private_irq->out_bit_pos = platform_irq->out_bit_pos;
+ private_irq->out_offset = platform_irq->out_offset;
+ private_irq->out_base = platform_irq->out_base;
+
+ irq_id = platform_get_irq_byname(
+ pdev,
+ platform_irq->irq_name
+ );
+ SMD_DBG("smd: %s: register irq: %s id: %d\n", __func__,
+ platform_irq->irq_name, irq_id);
+ ret = request_irq(irq_id,
+ private_irq->irq_handler,
+ platform_irq->flags,
+ platform_irq->device_name,
+ (void *)platform_irq->dev_id
+ );
+ if (ret < 0) {
+ platform_irq->irq_id = ret;
+ } else {
+ platform_irq->irq_id = irq_id;
+ ret_wake = enable_irq_wake(irq_id);
+ if (ret_wake < 0) {
+ pr_err("smd: enable_irq_wake failed on %s",
+ platform_irq->irq_name);
+ }
+ }
+
+ return ret;
+}
+
+int smd_core_platform_init(struct platform_device *pdev)
+{
+ int i;
+ int ret;
+ uint32_t num_ss;
+ struct smd_platform *smd_platform_data;
+ struct smd_subsystem_config *smd_ss_config_list;
+ struct smd_subsystem_config *cfg;
+ int err_ret = 0;
+
+ smd_platform_data = pdev->dev.platform_data;
+ num_ss = smd_platform_data->num_ss_configs;
+ smd_ss_config_list = smd_platform_data->smd_ss_configs;
+
+ for (i = 0; i < num_ss; i++) {
+ cfg = &smd_ss_config_list[i];
+
+ ret = intr_init(
+ &private_intr_config[cfg->irq_config_id].smd,
+ &cfg->smd_int,
+ pdev
+ );
+
+ if (ret < 0) {
+ err_ret = ret;
+ pr_err("smd: register irq failed on %s\n",
+ cfg->smd_int.irq_name);
+ break;
+ }
+
+ ret = intr_init(
+ &private_intr_config[cfg->irq_config_id].smsm,
+ &cfg->smsm_int,
+ pdev
+ );
+
+ if (ret < 0) {
+ err_ret = ret;
+ pr_err("smd: register irq failed on %s\n",
+ cfg->smsm_int.irq_name);
+ break;
+ }
+ }
+
+ if (err_ret < 0) {
+ pr_err("smd: deregistering IRQs\n");
+ for (i = 0; i < num_ss; ++i) {
+ cfg = &smd_ss_config_list[i];
+
+ if (cfg->smd_int.irq_id >= 0)
+ free_irq(cfg->smd_int.irq_id,
+ (void *)cfg->smd_int.dev_id
+ );
+ if (cfg->smsm_int.irq_id >= 0)
+ free_irq(cfg->smsm_int.irq_id,
+ (void *)cfg->smsm_int.dev_id
+ );
+ }
+ return err_ret;
+ }
+
+ SMD_INFO("smd_core_platform_init() done\n");
+ return 0;
+
+}
+
static int __devinit msm_smd_probe(struct platform_device *pdev)
{
- SMD_INFO("smd probe\n");
+ int ret;
+ SMD_INFO("smd probe\n");
INIT_WORK(&probe_work, smd_channel_probe_worker);
channel_close_wq = create_singlethread_workqueue("smd_channel_close");
@@ -2596,9 +2780,27 @@
return -1;
}
- if (smd_core_init()) {
- pr_err("smd_core_init() failed\n");
- return -1;
+ if (pdev) {
+ if (pdev->dev.of_node) {
+ pr_err("SMD: Device tree not currently supported\n");
+ return -ENODEV;
+ } else if (pdev->dev.platform_data) {
+ ret = smd_core_platform_init(pdev);
+ if (ret) {
+ pr_err(
+ "SMD: smd_core_platform_init() failed\n");
+ return -ENODEV;
+ }
+ } else {
+ ret = smd_core_init();
+ if (ret) {
+ pr_err("smd_core_init() failed\n");
+ return -ENODEV;
+ }
+ }
+ } else {
+ pr_err("SMD: PDEV not found\n");
+ return -ENODEV;
}
smd_initialized = 1;
@@ -2619,7 +2821,7 @@
{SMD_Q6, "lpass", .nb.notifier_call = restart_notifier_cb},
{SMD_WCNSS, "riva", .nb.notifier_call = restart_notifier_cb},
{SMD_DSPS, "dsps", .nb.notifier_call = restart_notifier_cb},
- {SMD_MODEM, "gnss", .nb.notifier_call = restart_notifier_cb},
+ {SMD_MODEM, "gss", .nb.notifier_call = restart_notifier_cb},
};
static int restart_notifier_cb(struct notifier_block *this,
diff --git a/arch/arm/mach-msm/spm-v2.c b/arch/arm/mach-msm/spm-v2.c
index 021a216..4a7cf91 100644
--- a/arch/arm/mach-msm/spm-v2.c
+++ b/arch/arm/mach-msm/spm-v2.c
@@ -18,7 +18,6 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <mach/msm_iomap.h>
-#include <mach/socinfo.h>
#include "spm_driver.h"
@@ -128,10 +127,6 @@
{
uint32_t value = enable ? 0x01 : 0x00;
- /* TODO: Remove this after 8064 bring up */
- if (cpu_is_apq8064())
- return 0;
-
if (!dev)
return -EINVAL;
@@ -150,10 +145,6 @@
int i;
int num_spm_entry = msm_spm_drv_get_num_spm_entry(dev);
- /* TODO: Remove this after 8064 bring up */
- if (cpu_is_apq8064())
- return;
-
if (!dev) {
__WARN();
return;
@@ -174,10 +165,6 @@
uint32_t offset_w = offset / 4;
int ret = 0;
- /* TODO: Remove this after 8064 bring up */
- if (cpu_is_apq8064())
- return 0;
-
if (!cmd || !dev) {
__WARN();
goto failed_write_seq_data;
@@ -214,10 +201,6 @@
uint32_t addr)
{
- /* TODO: Remove this after 8064 bring up */
- if (cpu_is_apq8064())
- return 0;
-
/* SPM is configured to reset start address to zero after end of Program
*/
if (!dev)
@@ -242,10 +225,6 @@
{
uint32_t timeout_us;
- /* TODO: Remove this after 8064 bring up */
- if (cpu_is_apq8064())
- return 0;
-
if (!dev)
return -EINVAL;
@@ -299,10 +278,6 @@
int i;
int num_spm_entry;
- /* TODO: Remove this after 8064 bring up */
- if (cpu_is_apq8064())
- return 0;
-
BUG_ON(!dev || !data);
dev->reg_base_addr = data->reg_base_addr;
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 0aa1358..883dec1 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -19,7 +19,6 @@
#include <linux/slab.h>
#include <mach/msm_iomap.h>
#include <mach/socinfo.h>
-
#include "spm.h"
#include "spm_driver.h"
@@ -130,11 +129,6 @@
int msm_spm_set_low_power_mode(unsigned int mode, bool notify_rpm)
{
struct msm_spm_device *dev = &__get_cpu_var(msm_cpu_spm_device);
-
- /* TODO: Remove this after 8064 bring up */
- if (cpu_is_apq8064())
- return 0;
-
return msm_spm_dev_set_low_power_mode(dev, mode, notify_rpm);
}
@@ -143,10 +137,6 @@
unsigned int cpu;
int ret = 0;
- /* TODO: Remove this after 8064 bring up */
- if (cpu_is_apq8064())
- return 0;
-
BUG_ON((nr_devs < num_possible_cpus()) || !data);
for_each_possible_cpu(cpu) {
@@ -210,10 +200,6 @@
int __init msm_spm_l2_init(struct msm_spm_platform_data *data)
{
- /* TODO: Remove this after 8064 bring up */
- if (cpu_is_apq8064())
- return 0;
-
return msm_spm_dev_init(&msm_spm_l2_device, data);
}
#endif
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 3d44075..e566234 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1087,7 +1087,8 @@
res = request_percpu_irq(ce->irq, msm_timer_interrupt,
ce->name, clock->percpu_evt);
if (!res)
- enable_percpu_irq(ce->irq, 0);
+ enable_percpu_irq(ce->irq,
+ IRQ_TYPE_EDGE_RISING);
} else {
clock->evt = ce;
res = request_irq(ce->irq, msm_timer_interrupt,
@@ -1150,7 +1151,7 @@
*__this_cpu_ptr(clock->percpu_evt) = evt;
clockevents_register_device(evt);
- enable_percpu_irq(evt->irq, 0);
+ enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
return 0;
}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index b4ca325..7d2e44f 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1136,3 +1136,4 @@
apq8064_cdp MACH_APQ8064_CDP APQ8064_CDP 3948
apq8064_mtp MACH_APQ8064_MTP APQ8064_MTP 3949
apq8064_liquid MACH_APQ8064_LIQUID APQ8064_LIQUID 3951
+msm7627a_qrd3 MACH_MSM7627A_QRD3 MSM7627A_QRD3 4005
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 7ceae89..07322cd 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -124,7 +124,8 @@
*/
int chk_apps_master(void)
{
- if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615())
+ if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615() ||
+ cpu_is_apq8064() || cpu_is_msm8627())
return 1;
else
return 0;
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index f2a2210..df2cd65 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -86,8 +86,8 @@
diagchar_ioctl(NULL, DIAG_IOCTL_COMMAND_REG,
(unsigned long)pkt_params);
kfree(temp);
- buf = buf + HDR_SIZ + data_len;
}
+ buf = buf + HDR_SIZ + data_len;
}
}
kfree(pkt_params);
diff --git a/drivers/char/hw_random/msm_rng.c b/drivers/char/hw_random/msm_rng.c
index b03a4ec..f5367ef 100644
--- a/drivers/char/hw_random/msm_rng.c
+++ b/drivers/char/hw_random/msm_rng.c
@@ -242,6 +242,9 @@
static int __init msm_rng_init(void)
{
+ if (cpu_is_apq8064())
+ return -ENODEV;
+
return platform_driver_register(&rng_driver);
}
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index fc1cfb6..a6b0cf6 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -27,9 +27,11 @@
#include <linux/memory_alloc.h>
#include <linux/seq_file.h>
#include <linux/fmem.h>
+#include <linux/iommu.h>
#include <mach/msm_memtypes.h>
#include <mach/scm.h>
-#include "ion_priv.h"
+#include <mach/iommu_domains.h>
+ #include "ion_priv.h"
#include <asm/mach/map.h>
@@ -566,6 +568,103 @@
return ret_value;
}
+static int ion_cp_heap_map_iommu(struct ion_buffer *buffer,
+ struct ion_iommu_map *data,
+ unsigned int domain_num,
+ unsigned int partition_num,
+ unsigned long align,
+ unsigned long iova_length,
+ unsigned long flags)
+{
+ unsigned long temp_phys, temp_iova;
+ struct iommu_domain *domain;
+ int i, ret = 0;
+ unsigned long extra;
+
+ data->mapped_size = iova_length;
+
+ if (!msm_use_iommu()) {
+ data->iova_addr = buffer->priv_phys;
+ return 0;
+ }
+
+ extra = iova_length - buffer->size;
+
+ data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
+ data->mapped_size, align);
+
+ if (!data->iova_addr) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ domain = msm_get_iommu_domain(domain_num);
+
+ if (!domain) {
+ ret = -ENOMEM;
+ goto out1;
+ }
+
+ temp_iova = data->iova_addr;
+ temp_phys = buffer->priv_phys;
+ for (i = buffer->size; i > 0; i -= SZ_4K, temp_iova += SZ_4K,
+ temp_phys += SZ_4K) {
+ ret = iommu_map(domain, temp_iova, temp_phys,
+ get_order(SZ_4K),
+ ION_IS_CACHED(flags) ? 1 : 0);
+
+ if (ret) {
+ pr_err("%s: could not map %lx to %lx in domain %p\n",
+ __func__, temp_iova, temp_phys, domain);
+ goto out2;
+ }
+ }
+
+ if (extra && (msm_iommu_map_extra(domain, temp_iova, extra, flags) < 0))
+ goto out2;
+
+ return 0;
+
+out2:
+ for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
+ iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+out1:
+ msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+ data->mapped_size);
+out:
+ return ret;
+}
+
+static void ion_cp_heap_unmap_iommu(struct ion_iommu_map *data)
+{
+ int i;
+ unsigned long temp_iova;
+ unsigned int domain_num;
+ unsigned int partition_num;
+ struct iommu_domain *domain;
+
+ if (!msm_use_iommu())
+ return;
+
+ domain_num = iommu_map_domain(data);
+ partition_num = iommu_map_partition(data);
+
+ domain = msm_get_iommu_domain(domain_num);
+
+ if (!domain) {
+ WARN(1, "Could not get domain %d. Corruption?\n", domain_num);
+ return;
+ }
+
+ temp_iova = data->iova_addr;
+ for (i = data->mapped_size; i > 0; i -= SZ_4K, temp_iova += SZ_4K)
+ iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+
+ msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+ data->mapped_size);
+
+ return;
+}
static struct ion_heap_ops cp_heap_ops = {
.allocate = ion_cp_heap_allocate,
@@ -581,6 +680,8 @@
.print_debug = ion_cp_print_debug,
.secure_heap = ion_cp_secure_heap,
.unsecure_heap = ion_cp_unsecure_heap,
+ .map_iommu = ion_cp_heap_map_iommu,
+ .unmap_iommu = ion_cp_heap_unmap_iommu,
};
struct ion_heap *ion_cp_heap_create(struct ion_platform_heap *heap_data)
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index b44dccc..9cbebbe 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -131,31 +131,35 @@
struct adreno_gpudev *gpudev;
unsigned int istore_size;
unsigned int pix_shader_start;
+ unsigned int instruction_size; /* Size of an instruction in dwords */
} adreno_gpulist[] = {
{ ADRENO_REV_A200, 0, 2, ANY_ID, ANY_ID,
"yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev,
- 512, 384},
+ 512, 384, 3},
{ ADRENO_REV_A205, 0, 1, 0, ANY_ID,
"yamato_pm4.fw", "yamato_pfp.fw", &adreno_a2xx_gpudev,
- 512, 384},
+ 512, 384, 3},
{ ADRENO_REV_A220, 2, 1, ANY_ID, ANY_ID,
"leia_pm4_470.fw", "leia_pfp_470.fw", &adreno_a2xx_gpudev,
- 512, 384},
+ 512, 384, 3},
/*
* patchlevel 5 (8960v2) needs special pm4 firmware to work around
* a hardware problem.
*/
{ ADRENO_REV_A225, 2, 2, 0, 5,
"a225p5_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
- 1536, 768 },
+ 1536, 768, 3 },
{ ADRENO_REV_A225, 2, 2, 0, 6,
"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
- 1536, 768 },
+ 1536, 768, 3 },
{ ADRENO_REV_A225, 2, 2, ANY_ID, ANY_ID,
"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
- 1536, 768 },
+ 1536, 768, 3 },
+ /* A3XX doesn't use the pix_shader_start */
{ ADRENO_REV_A320, 3, 1, ANY_ID, ANY_ID,
- "a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev },
+ "a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
+ 512, 0, 2 },
+
};
static irqreturn_t adreno_isr(int irq, void *data)
@@ -248,6 +252,16 @@
unsigned int mh_mmu_invalidate = 0x00000003; /*invalidate all and tc */
/*
+ * A3XX doesn't support the fast path (the registers don't even exist)
+ * so just bail out early
+ */
+
+ if (adreno_is_a3xx(adreno_dev)) {
+ kgsl_mmu_device_setstate(device, flags);
+ return;
+ }
+
+ /*
* If possible, then set the state via the command stream to avoid
* a CPU idle. Otherwise, use the default setstate which uses register
* writes For CFF dump we must idle and use the registers so that it is
@@ -442,6 +456,7 @@
adreno_dev->pm4_fwfile = adreno_gpulist[i].pm4fw;
adreno_dev->istore_size = adreno_gpulist[i].istore_size;
adreno_dev->pix_shader_start = adreno_gpulist[i].pix_shader_start;
+ adreno_dev->instruction_size = adreno_gpulist[i].instruction_size;
}
static int __devinit
@@ -565,6 +580,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/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 9c2d704..9498b80 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -39,12 +39,7 @@
#define ADRENO_DEFAULT_PWRSCALE_POLICY NULL
#endif
-/*
- * constants for the size of shader instructions
- */
-#define ADRENO_ISTORE_BYTES 12
-#define ADRENO_ISTORE_WORDS 3
-#define ADRENO_ISTORE_START 0x5000
+#define ADRENO_ISTORE_START 0x5000 /* Istore offset */
enum adreno_gpurev {
ADRENO_REV_UNKNOWN = 0,
@@ -75,6 +70,7 @@
unsigned int wait_timeout;
unsigned int istore_size;
unsigned int pix_shader_start;
+ unsigned int instruction_size;
};
struct adreno_gpudev {
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index e31b76b..f2b1278 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -164,7 +164,8 @@
static inline int _shader_shadow_size(struct adreno_device *adreno_dev)
{
- return adreno_dev->istore_size*ADRENO_ISTORE_BYTES;
+ return adreno_dev->istore_size *
+ (adreno_dev->instruction_size * sizeof(unsigned int));
}
static inline int _context_size(struct adreno_device *adreno_dev)
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 1bad811..f68bc41 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -34,7 +34,7 @@
0x01ea, 0x01ea, 0x01ee, 0x01f1, 0x01f5, 0x01f5, 0x01fc, 0x01ff,
0x0440, 0x0440, 0x0443, 0x0443, 0x0445, 0x0445, 0x044d, 0x044f,
0x0452, 0x0452, 0x0454, 0x046f, 0x047c, 0x047c, 0x047f, 0x047f,
- 0x0579, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e,
+ 0x0578, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e,
0x0612, 0x0614, 0x0c01, 0x0c02, 0x0c06, 0x0c1d, 0x0c3d, 0x0c3f,
0x0c48, 0x0c4b, 0x0c80, 0x0c80, 0x0c88, 0x0c8b, 0x0ca0, 0x0cb7,
0x0cc0, 0x0cc1, 0x0cc6, 0x0cc7, 0x0ce4, 0x0ce5, 0x0e00, 0x0e05,
@@ -127,13 +127,8 @@
#define HLSQ_MEMOBJ_OFFSET 0x400
#define HLSQ_MIPMAP_OFFSET 0x800
-#ifdef GSL_USE_A3XX_HLSQ_SHADOW_RAM
/* Use shadow RAM */
#define HLSQ_SHADOW_BASE (0x10000+SSIZE*2)
-#else
-/* Use working RAM */
-#define HLSQ_SHADOW_BASE 0x10000
-#endif
#define REG_TO_MEM_LOOP_COUNT_SHIFT 15
@@ -258,7 +253,7 @@
struct adreno_context *drawctxt)
{
unsigned int *cmd = tmp_ctx.cmd;
- unsigned int *start = cmd;
+ unsigned int *start;
unsigned int i;
drawctxt->constant_save_commands[0].hostptr = cmd;
@@ -266,6 +261,8 @@
virt2gpu(cmd, &drawctxt->gpustate);
cmd++;
+ start = cmd;
+
*cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
*cmd++ = 0;
@@ -1313,7 +1310,8 @@
_SET(SP_FSCTRLREG1_FSINITIALOUTSTANDING, 2) |
_SET(SP_FSCTRLREG1_HALFPRECVAROFFSET, 63);
/* SP_FS_OBJ_OFFSET_REG */
- *cmds++ = _SET(SP_OBJOFFSETREG_CONSTOBJECTSTARTOFFSET, 128);
+ *cmds++ = _SET(SP_OBJOFFSETREG_CONSTOBJECTSTARTOFFSET, 128) |
+ _SET(SP_OBJOFFSETREG_SHADEROBJOFFSETINIC, 1);
/* SP_FS_OBJ_START_REG */
*cmds++ = 0x00000000;
@@ -1329,7 +1327,7 @@
/* SP_FS_OUT_REG */
*cmds++ = _SET(SP_FSOUTREG_PAD0, SP_PIXEL_BASED);
- *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
+ *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
*cmds++ = CP_REG(A3XX_SP_FS_MRT_REG_0);
/* SP_FS_MRT_REG0 */
*cmds++ = _SET(SP_FSMRTREG_REGID, 4);
@@ -1426,7 +1424,7 @@
_SET(VPC_VPCVARPSREPLMODE_COMPONENT16, 1) |
_SET(VPC_VPCVARPSREPLMODE_COMPONENT17, 2);
- *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 11);
+ *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
*cmds++ = CP_REG(A3XX_SP_SP_CTRL_REG);
/* SP_SP_CTRL_REG */
*cmds++ = _SET(SP_SPCTRLREG_SLEEPMODE, 1);
@@ -1652,7 +1650,9 @@
*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
*cmds++ = CP_REG(A3XX_GRAS_SC_CONTROL);
/* GRAS_SC_CONTROL */
- *cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1);
+ /*cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1);
+ *cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1) |*/
+ *cmds++ = 0x04001000;
*cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
*cmds++ = CP_REG(A3XX_GRAS_SU_MODE_CONTROL);
@@ -2130,24 +2130,17 @@
static int a3xx_create_gmem_shadow(struct adreno_device *adreno_dev,
struct adreno_context *drawctxt)
{
+ int result;
+
calc_gmemsize(&drawctxt->context_gmem_shadow,
adreno_dev->gmemspace.sizebytes);
tmp_ctx.gmem_base = adreno_dev->gmemspace.gpu_base;
- if (drawctxt->flags & CTXT_FLAGS_GMEM_SHADOW) {
- int result =
- kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
- drawctxt->pagetable,
- drawctxt->context_gmem_shadow.size);
+ result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
+ drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
- if (result)
- return result;
- } else {
- memset(&drawctxt->context_gmem_shadow.gmemshadow, 0,
- sizeof(drawctxt->context_gmem_shadow.gmemshadow));
-
- return 0;
- }
+ if (result)
+ return result;
build_quad_vtxbuff(drawctxt, &drawctxt->context_gmem_shadow,
&tmp_ctx.cmd);
@@ -2163,6 +2156,8 @@
kgsl_cache_range_op(&drawctxt->context_gmem_shadow.gmemshadow,
KGSL_CACHE_OP_FLUSH);
+ drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW;
+
return 0;
}
@@ -2431,10 +2426,7 @@
#define A3XX_INT_MASK \
((1 << A3XX_INT_RBBM_AHB_ERROR) | \
(1 << A3XX_INT_RBBM_REG_TIMEOUT) | \
- (1 << A3XX_INT_RBBM_ME_MS_TIMEOUT) | \
- (1 << A3XX_INT_RBBM_PFP_MS_TIMEOUT) | \
(1 << A3XX_INT_RBBM_ATB_BUS_OVERFLOW) | \
- (1 << A3XX_INT_VFD_ERROR) | \
(1 << A3XX_INT_CP_T0_PACKET_IN_IB) | \
(1 << A3XX_INT_CP_OPCODE_ERROR) | \
(1 << A3XX_INT_CP_RESERVED_BIT_ERROR) | \
@@ -2444,7 +2436,6 @@
(1 << A3XX_INT_CP_RB_INT) | \
(1 << A3XX_INT_CP_REG_PROTECT_FAULT) | \
(1 << A3XX_INT_CP_AHB_ERROR_HALT) | \
- (1 << A3XX_INT_MISC_HANG_DETECT) | \
(1 << A3XX_INT_UCHE_OOB_ACCESS))
static struct {
@@ -2474,7 +2465,7 @@
A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 21 - CP_AHB_ERROR_FAULT */
A3XX_IRQ_CALLBACK(NULL), /* 22 - Unused */
A3XX_IRQ_CALLBACK(NULL), /* 23 - Unused */
- A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 24 - MISC_HANG_DETECT */
+ A3XX_IRQ_CALLBACK(NULL), /* 24 - MISC_HANG_DETECT */
A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 25 - UCHE_OOB_ACCESS */
/* 26 to 31 - Unused */
};
@@ -2547,6 +2538,9 @@
{
struct kgsl_device *device = &adreno_dev->dev;
+ /* GMEM size on A320 is 512K */
+ adreno_dev->gmemspace.sizebytes = SZ_512K;
+
/* Reset the core */
adreno_regwrite(device, A3XX_RBBM_SW_RESET_CMD,
0x00000001);
@@ -2570,10 +2564,17 @@
adreno_regwrite(device, A3XX_RBBM_AHB_CTL0, 0x00000001);
/* Enable AHB error reporting */
- adreno_regwrite(device, A3XX_RBBM_AHB_CTL1, 0xA6FFFFFF);
+ adreno_regwrite(device, A3XX_RBBM_AHB_CTL1, 0x86FFFFFF);
/* Turn on the power counters */
adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, 0x00003000);
+
+ /* Turn on hang detection - this spews a lot of useful information
+ * into the RBBM registers on a hang */
+
+ adreno_regwrite(device, A3XX_RBBM_INTERFACE_HANG_INT_CTL,
+ (1 << 16) | 0xFFF);
+
}
/* Defined in adreno_a3xx_snapshot.c */
diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c
index aade50c..c8c7c44 100644
--- a/drivers/gpu/msm/adreno_a3xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c
@@ -80,7 +80,7 @@
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct kgsl_snapshot_debug *header = snapshot;
unsigned int *data = snapshot + sizeof(*header);
- int i, size = adreno_dev->pm4_fw_size >> 2;
+ int i, size = adreno_dev->pm4_fw_size - 1;
if (remain < DEBUG_SECTION_SZ(size)) {
SNAPSHOT_ERR_NOMEM(device, "CP PM4 RAM DEBUG");
@@ -98,7 +98,7 @@
*/
adreno_regwrite(device, REG_CP_ME_RAM_RADDR, 0x0);
- for (i = 0; i < adreno_dev->pm4_fw_size >> 2; i++)
+ for (i = 0; i < size; i++)
adreno_regread(device, REG_CP_ME_RAM_DATA, &data[i]);
return DEBUG_SECTION_SZ(size);
@@ -110,7 +110,7 @@
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct kgsl_snapshot_debug *header = snapshot;
unsigned int *data = snapshot + sizeof(*header);
- int i, size = adreno_dev->pfp_fw_size >> 2;
+ int i, size = adreno_dev->pfp_fw_size - 1;
if (remain < DEBUG_SECTION_SZ(size)) {
SNAPSHOT_ERR_NOMEM(device, "CP PFP RAM DEBUG");
@@ -127,7 +127,7 @@
* maintain always changing hardcoded constants
*/
kgsl_regwrite(device, A3XX_CP_PFP_UCODE_ADDR, 0x0);
- for (i = 0; i < adreno_dev->pfp_fw_size >> 2; i++)
+ for (i = 0; i < size; i++)
adreno_regread(device, A3XX_CP_PFP_UCODE_DATA, &data[i]);
return DEBUG_SECTION_SZ(size);
@@ -175,7 +175,7 @@
return 0;
}
- val = (id << 0x06) | (1 << 0x10);
+ val = (id << 8) | (1 << 16);
header->id = id;
header->count = DEBUGFS_BLOCK_SIZE;
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index c1b9e4c..b53ca8f 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -143,7 +143,8 @@
return 0;
adreno_dev = ADRENO_DEVICE(device);
- count = adreno_dev->istore_size * ADRENO_ISTORE_WORDS;
+ count = adreno_dev->istore_size * adreno_dev->instruction_size;
+
remaining = count;
for (i = 0; i < count; i += rowc) {
unsigned int vals[rowc];
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 9bf85cf..aeb89b3 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -86,7 +86,7 @@
gmem_restore_quad[7] = uint2float(shadow->width);
memcpy(shadow->quad_vertices.hostptr, gmem_copy_quad, QUAD_LEN << 2);
- memcpy(shadow->quad_vertices_restore.hostptr, gmem_copy_quad,
+ memcpy(shadow->quad_vertices_restore.hostptr, gmem_restore_quad,
QUAD_RESTORE_LEN << 2);
memcpy(shadow->quad_texcoords.hostptr, gmem_copy_texcoord,
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index fb88a72..cc3f3e7 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -86,7 +86,7 @@
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
int count, i;
- count = adreno_dev->istore_size * ADRENO_ISTORE_WORDS;
+ count = adreno_dev->istore_size * adreno_dev->instruction_size;
if (remain < (count * 4) + sizeof(*header)) {
KGSL_DRV_ERR(device,
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 1b6696b..512a262 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2231,6 +2231,7 @@
int kgsl_device_platform_probe(struct kgsl_device *device,
irqreturn_t (*dev_isr) (int, void*))
{
+ int result;
int status = -EINVAL;
struct kgsl_memregion *regspace = NULL;
struct resource *res;
@@ -2291,6 +2292,9 @@
device->id, regspace->mmio_phys_base,
regspace->sizebytes, regspace->mmio_virt_base);
+ result = kgsl_drm_init(pdev);
+ if (result)
+ goto error_iounmap;
status = kgsl_register_device(device);
if (!status)
@@ -2426,11 +2430,6 @@
goto err;
}
- result = kgsl_drm_init(NULL);
-
- if (result)
- goto err;
-
return 0;
err:
diff --git a/drivers/gpu/msm/kgsl_drm.c b/drivers/gpu/msm/kgsl_drm.c
index dba2dfc..e3f6f3b 100644
--- a/drivers/gpu/msm/kgsl_drm.c
+++ b/drivers/gpu/msm/kgsl_drm.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.
*
* 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
@@ -17,7 +17,6 @@
#include "drmP.h"
#include "drm.h"
#include <linux/android_pmem.h>
-#include <linux/notifier.h>
#include "kgsl.h"
#include "kgsl_device.h"
@@ -39,6 +38,9 @@
#define ENTRY_EMPTY -1
#define ENTRY_NEEDS_CLEANUP -2
+#define DRM_KGSL_NOT_INITED -1
+#define DRM_KGSL_INITED 1
+
#define DRM_KGSL_NUM_FENCE_ENTRIES (DRM_KGSL_HANDLE_WAIT_ENTRIES << 2)
#define DRM_KGSL_HANDLE_WAIT_ENTRIES 5
@@ -127,6 +129,8 @@
struct list_head wait_list;
};
+static int kgsl_drm_inited = DRM_KGSL_NOT_INITED;
+
/* This is a global list of all the memory currently mapped in the MMU */
static struct list_head kgsl_mem_list;
@@ -186,41 +190,6 @@
struct kgsl_device_private *devpriv[KGSL_DEVICE_MAX];
};
-static int kgsl_ts_notifier_cb(struct notifier_block *blk,
- unsigned long code, void *_param);
-
-static struct notifier_block kgsl_ts_nb[KGSL_DEVICE_MAX];
-
-static int kgsl_drm_firstopen(struct drm_device *dev)
-{
- int i;
-
- for (i = 0; i < KGSL_DEVICE_MAX; i++) {
- struct kgsl_device *device = kgsl_get_device(i);
-
- if (device == NULL)
- continue;
-
- kgsl_ts_nb[i].notifier_call = kgsl_ts_notifier_cb;
- kgsl_register_ts_notifier(device, &kgsl_ts_nb[i]);
- }
-
- return 0;
-}
-
-void kgsl_drm_lastclose(struct drm_device *dev)
-{
- int i;
-
- for (i = 0; i < KGSL_DEVICE_MAX; i++) {
- struct kgsl_device *device = kgsl_get_device(i);
- if (device == NULL)
- continue;
-
- kgsl_unregister_ts_notifier(device, &kgsl_ts_nb[i]);
- }
-}
-
void kgsl_drm_preclose(struct drm_device *dev, struct drm_file *file_priv)
{
}
@@ -268,74 +237,72 @@
{
struct drm_kgsl_gem_object *priv = obj->driver_private;
int index;
+ int result = 0;
/* Return if the memory is already allocated */
if (kgsl_gem_memory_allocated(obj) || TYPE_IS_FD(priv->type))
return 0;
+ if (priv->pagetable == NULL) {
+ priv->pagetable = kgsl_mmu_getpagetable(KGSL_MMU_GLOBAL_PT);
+
+ if (priv->pagetable == NULL) {
+ DRM_ERROR("Unable to get the GPU MMU pagetable\n");
+ return -EINVAL;
+ }
+ }
+
if (TYPE_IS_PMEM(priv->type)) {
int type;
if (priv->type == DRM_KGSL_GEM_TYPE_EBI ||
- priv->type & DRM_KGSL_GEM_PMEM_EBI)
- type = PMEM_MEMTYPE_EBI1;
- else
- type = PMEM_MEMTYPE_SMI;
-
- priv->memdesc.physaddr =
- pmem_kalloc(obj->size * priv->bufcount,
- type | PMEM_ALIGNMENT_4K);
-
- if (IS_ERR((void *) priv->memdesc.physaddr)) {
- DRM_ERROR("Unable to allocate PMEM memory\n");
- return -ENOMEM;
+ priv->type & DRM_KGSL_GEM_PMEM_EBI) {
+ type = PMEM_MEMTYPE_EBI1;
+ result = kgsl_sharedmem_ebimem_user(
+ &priv->memdesc,
+ priv->pagetable,
+ obj->size * priv->bufcount,
+ 0);
+ if (result) {
+ DRM_ERROR(
+ "Unable to allocate PMEM memory\n");
+ return result;
+ }
}
-
- priv->memdesc.size = obj->size * priv->bufcount;
+ else
+ return -EINVAL;
} else if (TYPE_IS_MEM(priv->type)) {
- priv->memdesc.hostptr =
- vmalloc_user(obj->size * priv->bufcount);
- if (priv->memdesc.hostptr == NULL) {
- DRM_ERROR("Unable to allocate vmalloc memory\n");
- return -ENOMEM;
+ if (priv->type == DRM_KGSL_GEM_TYPE_KMEM ||
+ priv->type & DRM_KGSL_GEM_CACHE_MASK)
+ list_add(&priv->list, &kgsl_mem_list);
+
+ result = kgsl_sharedmem_vmalloc_user(&priv->memdesc,
+ priv->pagetable,
+ obj->size * priv->bufcount, 0);
+
+ if (result != 0) {
+ DRM_ERROR(
+ "Unable to allocate Vmalloc user memory\n");
+ return result;
}
-
- priv->memdesc.size = obj->size * priv->bufcount;
- priv->memdesc.ops = &kgsl_vmalloc_ops;
} else
return -EINVAL;
- for (index = 0; index < priv->bufcount; index++)
+ for (index = 0; index < priv->bufcount; index++) {
priv->bufs[index].offset = index * obj->size;
-
+ priv->bufs[index].gpuaddr =
+ priv->memdesc.gpuaddr +
+ priv->bufs[index].offset;
+ }
+ priv->flags |= DRM_KGSL_GEM_FLAG_MAPPED;
return 0;
}
static void
-kgsl_gem_unmap(struct drm_gem_object *obj)
-{
- struct drm_kgsl_gem_object *priv = obj->driver_private;
-
- if (!priv->flags & DRM_KGSL_GEM_FLAG_MAPPED)
- return;
-
- kgsl_mmu_unmap(priv->pagetable, &priv->memdesc);
-
- kgsl_mmu_putpagetable(priv->pagetable);
- priv->pagetable = NULL;
-
- if ((priv->type == DRM_KGSL_GEM_TYPE_KMEM) ||
- (priv->type & DRM_KGSL_GEM_CACHE_MASK))
- list_del(&priv->list);
-
- priv->flags &= ~DRM_KGSL_GEM_FLAG_MAPPED;
-}
-
-static void
kgsl_gem_free_memory(struct drm_gem_object *obj)
{
struct drm_kgsl_gem_object *priv = obj->driver_private;
@@ -346,12 +313,17 @@
kgsl_gem_mem_flush(&priv->memdesc, priv->type,
DRM_KGSL_GEM_CACHE_OP_FROM_DEV);
- kgsl_gem_unmap(obj);
-
- if (TYPE_IS_PMEM(priv->type))
- pmem_kfree(priv->memdesc.physaddr);
-
kgsl_sharedmem_free(&priv->memdesc);
+
+ kgsl_mmu_putpagetable(priv->pagetable);
+ priv->pagetable = NULL;
+
+ if ((priv->type == DRM_KGSL_GEM_TYPE_KMEM) ||
+ (priv->type & DRM_KGSL_GEM_CACHE_MASK))
+ list_del(&priv->list);
+
+ priv->flags &= ~DRM_KGSL_GEM_FLAG_MAPPED;
+
}
int
@@ -447,7 +419,7 @@
filp = fget(drm_fd);
if (unlikely(filp == NULL)) {
- DRM_ERROR("Unable to ghet the DRM file descriptor\n");
+ DRM_ERROR("Unable to get the DRM file descriptor\n");
return -EINVAL;
}
file_priv = filp->private_data;
@@ -520,7 +492,7 @@
ret = drm_gem_handle_create(file_priv, obj, handle);
- drm_gem_object_handle_unreference(obj);
+ drm_gem_object_unreference(obj);
INIT_LIST_HEAD(&priv->wait_list);
for (i = 0; i < DRM_KGSL_HANDLE_WAIT_ENTRIES; i++) {
@@ -695,109 +667,14 @@
kgsl_gem_unbind_gpu_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- struct drm_kgsl_gem_bind_gpu *args = data;
- struct drm_gem_object *obj;
- struct drm_kgsl_gem_object *priv;
-
- obj = drm_gem_object_lookup(dev, file_priv, args->handle);
-
- if (obj == NULL) {
- DRM_ERROR("Invalid GEM handle %x\n", args->handle);
- return -EBADF;
- }
-
- mutex_lock(&dev->struct_mutex);
- priv = obj->driver_private;
-
- if (--priv->bound == 0)
- kgsl_gem_unmap(obj);
-
- drm_gem_object_unreference(obj);
- mutex_unlock(&dev->struct_mutex);
return 0;
}
-static int
-kgsl_gem_map(struct drm_gem_object *obj)
-{
- struct drm_kgsl_gem_object *priv = obj->driver_private;
- int index;
- int ret = -EINVAL;
-
- if (priv->flags & DRM_KGSL_GEM_FLAG_MAPPED)
- return 0;
-
- /* Get the global page table */
-
- if (priv->pagetable == NULL) {
- priv->pagetable = kgsl_mmu_getpagetable(KGSL_MMU_GLOBAL_PT);
-
- if (priv->pagetable == NULL) {
- DRM_ERROR("Unable to get the GPU MMU pagetable\n");
- return -EINVAL;
- }
- }
-
- priv->memdesc.pagetable = priv->pagetable;
-
- ret = kgsl_mmu_map(priv->pagetable, &priv->memdesc,
- GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
-
- if (!ret) {
- for (index = 0; index < priv->bufcount; index++) {
- priv->bufs[index].gpuaddr =
- priv->memdesc.gpuaddr +
- priv->bufs[index].offset;
- }
- }
-
- /* Add cached memory to the list to be cached */
-
- if (priv->type == DRM_KGSL_GEM_TYPE_KMEM ||
- priv->type & DRM_KGSL_GEM_CACHE_MASK)
- list_add(&priv->list, &kgsl_mem_list);
-
- priv->flags |= DRM_KGSL_GEM_FLAG_MAPPED;
-
- return ret;
-}
-
int
kgsl_gem_bind_gpu_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- struct drm_kgsl_gem_bind_gpu *args = data;
- struct drm_gem_object *obj;
- struct drm_kgsl_gem_object *priv;
- int ret = 0;
-
- obj = drm_gem_object_lookup(dev, file_priv, args->handle);
-
- if (obj == NULL) {
- DRM_ERROR("Invalid GEM handle %x\n", args->handle);
- return -EBADF;
- }
-
- mutex_lock(&dev->struct_mutex);
- priv = obj->driver_private;
-
- if (priv->bound++ == 0) {
-
- if (!kgsl_gem_memory_allocated(obj)) {
- DRM_ERROR("Memory not allocated for this object\n");
- ret = -ENOMEM;
- goto out;
- }
-
- ret = kgsl_gem_map(obj);
-
- /* This is legacy behavior - use GET_BUFFERINFO instead */
- args->gpuptr = priv->bufs[0].gpuaddr;
- }
-out:
- drm_gem_object_unreference(obj);
- mutex_unlock(&dev->struct_mutex);
- return ret;
+ return 0;
}
/* Allocate the memory and prepare it for CPU mapping */
@@ -1344,27 +1221,6 @@
fence->fence_id = ENTRY_NEEDS_CLEANUP; /* Mark it as needing cleanup */
}
-static int kgsl_ts_notifier_cb(struct notifier_block *blk,
- unsigned long code, void *_param)
-{
- struct drm_kgsl_gem_object_fence *fence;
- struct kgsl_device *device = kgsl_get_device(code);
- int i;
-
- /* loop through the fences to see what things can be processed */
-
- for (i = 0; i < DRM_KGSL_NUM_FENCE_ENTRIES; i++) {
- fence = &gem_buf_fence[i];
- if (!fence->ts_valid || fence->ts_device != code)
- continue;
-
- if (kgsl_check_timestamp(device, fence->timestamp))
- wakeup_fence_entries(fence);
- }
-
- return 0;
-}
-
int
kgsl_gem_lock_handle_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
@@ -1608,11 +1464,9 @@
};
static struct drm_driver driver = {
- .driver_features = DRIVER_USE_PLATFORM_DEVICE | DRIVER_GEM,
+ .driver_features = DRIVER_GEM,
.load = kgsl_drm_load,
.unload = kgsl_drm_unload,
- .firstopen = kgsl_drm_firstopen,
- .lastclose = kgsl_drm_lastclose,
.preclose = kgsl_drm_preclose,
.suspend = kgsl_drm_suspend,
.resume = kgsl_drm_resume,
@@ -1643,8 +1497,13 @@
{
int i;
+ /* Only initialize once */
+ if (kgsl_drm_inited == DRM_KGSL_INITED)
+ return 0;
+
+ kgsl_drm_inited = DRM_KGSL_INITED;
+
driver.num_ioctls = DRM_ARRAY_SIZE(kgsl_drm_ioctls);
- driver.platform_device = dev;
INIT_LIST_HEAD(&kgsl_mem_list);
@@ -1654,10 +1513,11 @@
gem_buf_fence[i].fence_id = ENTRY_EMPTY;
}
- return drm_init(&driver);
+ return drm_platform_init(&driver, dev);
}
void kgsl_drm_exit(void)
{
- drm_exit(&driver);
+ kgsl_drm_inited = DRM_KGSL_NOT_INITED;
+ drm_platform_exit(&driver, driver.kdriver.platform_device);
}
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 36248ef..671479e 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/iommu.h>
+#include <mach/socinfo.h>
#include "kgsl.h"
#include "kgsl_mmu.h"
@@ -534,9 +535,16 @@
int ret;
if (kgsl_mmu_type == KGSL_MMU_TYPE_NONE) {
- memdesc->gpuaddr = memdesc->physaddr;
- return 0;
+ if (memdesc->sglen == 1) {
+ memdesc->gpuaddr = sg_phys(memdesc->sg);
+ return 0;
+ } else {
+ KGSL_CORE_ERR("Memory is not contigious "
+ "(sglen = %d)\n", memdesc->sglen);
+ return -EINVAL;
+ }
}
+
memdesc->gpuaddr = gen_pool_alloc_aligned(pagetable->pool,
memdesc->size, KGSL_MMU_ALIGN_SHIFT);
@@ -712,7 +720,14 @@
void kgsl_mmu_set_mmutype(char *mmutype)
{
- kgsl_mmu_type = iommu_found() ? KGSL_MMU_TYPE_IOMMU : KGSL_MMU_TYPE_GPU;
+ /* Set the default MMU - GPU on <=8960 and nothing on >= 8064 */
+ kgsl_mmu_type =
+ cpu_is_apq8064() ? KGSL_MMU_TYPE_NONE : KGSL_MMU_TYPE_GPU;
+
+ /* Use the IOMMU if it is found */
+ if (iommu_found())
+ kgsl_mmu_type = KGSL_MMU_TYPE_IOMMU;
+
if (mmutype && !strncmp(mmutype, "gpummu", 6))
kgsl_mmu_type = KGSL_MMU_TYPE_GPU;
if (iommu_found() && mmutype && !strncmp(mmutype, "iommu", 5))
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index f99a546..9f2e3bd 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -33,6 +33,7 @@
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/gpio.h>
+#include <mach/socinfo.h>
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.2");
@@ -303,6 +304,30 @@
return 0;
}
+/*
+ * Before calling qup_config_core_on_en(), please make
+ * sure that QuPE core is in RESET state.
+ *
+ * Configuration of CORE_ON_EN - BIT13 in QUP_CONFIG register
+ * is only required for targets like 7x27a, where it needs
+ * be turned on for disabling the QuPE pclks.
+ */
+static void
+qup_config_core_on_en(struct qup_i2c_dev *dev)
+{
+ uint32_t status;
+
+ if (!(cpu_is_msm7x27a() || cpu_is_msm7x27aa() ||
+ cpu_is_msm7x25a() || cpu_is_msm7x25aa()))
+ return;
+
+ status = readl_relaxed(dev->base + QUP_CONFIG);
+ status |= BIT(13);
+ writel_relaxed(status, dev->base + QUP_CONFIG);
+ /* making sure that write has really gone through */
+ mb();
+}
+
static void
qup_i2c_pwr_mgmt(struct qup_i2c_dev *dev, unsigned int state)
{
@@ -313,6 +338,7 @@
} else {
qup_update_state(dev, QUP_RESET_STATE);
clk_disable_unprepare(dev->clk);
+ qup_config_core_on_en(dev);
clk_disable_unprepare(dev->pclk);
}
}
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index b1dc87e..ca44c34 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -226,3 +226,11 @@
by QUP in the board file as QUP is used by
applications other than camera.
+config S5K3L1YX
+ bool "Sensor S5K3L1YX (BAYER 12M)"
+ depends on MSM_CAMERA
+ ---help---
+ Samsung 12 MP Bayer Sensor with auto focus, uses
+ 4 mipi lanes, preview config = 1984 * 1508 at 30 fps,
+ snapshot config = 4000 * 3000 at 20 fps,
+ hfr video at 60, 90 and 120 fps.
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index af61bd2..86d62c9 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.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
@@ -73,43 +73,54 @@
static struct ispif_device *ispif;
+atomic_t ispif_irq_cnt;
+spinlock_t ispif_tasklet_lock;
+struct list_head ispif_tasklet_q;
static uint32_t global_intf_cmd_mask = 0xFFFFFFFF;
-static int msm_ispif_intf_reset(uint8_t intftype)
+
+static int msm_ispif_intf_reset(uint8_t intfmask)
{
int rc = 0;
- uint32_t data;
+ uint32_t data = 0x1;
+ uint8_t intfnum = 0, mask = intfmask;
+ while (mask != 0) {
+ if (!(intfmask & (0x1 << intfnum))) {
+ mask >>= 1;
+ intfnum++;
+ continue;
+ }
+ switch (intfnum) {
+ case PIX0:
+ data = (0x1 << STROBED_RST_EN) +
+ (0x1 << PIX_VFE_RST_STB) +
+ (0x1 << PIX_CSID_RST_STB);
+ break;
- switch (intftype) {
- case PIX0:
- data = (0x1 << STROBED_RST_EN) +
- (0x1 << PIX_VFE_RST_STB) +
- (0x1 << PIX_CSID_RST_STB);
+ case RDI0:
+ data = (0x1 << STROBED_RST_EN) +
+ (0x1 << RDI_VFE_RST_STB) +
+ (0x1 << RDI_CSID_RST_STB);
+ break;
+
+ case RDI1:
+ data = (0x1 << STROBED_RST_EN) +
+ (0x1 << RDI_1_VFE_RST_STB) +
+ (0x1 << RDI_1_CSID_RST_STB);
+ break;
+
+ default:
+ rc = -EINVAL;
+ break;
+ }
+ mask >>= 1;
+ intfnum++;
+ } /*end while */
+ if (rc >= 0) {
msm_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
- break;
-
- case RDI0:
- data = (0x1 << STROBED_RST_EN) +
- (0x1 << RDI_VFE_RST_STB) +
- (0x1 << RDI_CSID_RST_STB);
- msm_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
- break;
-
- case RDI1:
- data = (0x1 << STROBED_RST_EN) +
- (0x1 << RDI_1_VFE_RST_STB) +
- (0x1 << RDI_1_CSID_RST_STB);
- msm_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR);
- break;
-
- default:
- rc = -EINVAL;
- break;
+ rc = wait_for_completion_interruptible(&ispif->reset_complete);
}
- if (rc >= 0)
- rc = wait_for_completion_interruptible(
- &ispif->reset_complete);
return rc;
}
@@ -244,97 +255,109 @@
}
static void
-msm_ispif_intf_cmd(uint8_t intftype, uint8_t intf_cmd_mask)
+msm_ispif_intf_cmd(uint8_t intfmask, uint8_t intf_cmd_mask)
{
uint8_t vc = 0, val = 0;
- uint32_t cid_mask = msm_ispif_get_cid_mask(intftype);
-
- while (cid_mask != 0) {
- if ((cid_mask & 0xf) != 0x0) {
- val = (intf_cmd_mask>>(vc*2)) & 0x3;
- global_intf_cmd_mask &= ~((0x3 & ~val)
- <<((vc*2)+(intftype*8)));
- CDBG("intf cmd 0x%x\n", global_intf_cmd_mask);
- msm_io_w(global_intf_cmd_mask,
- ispif->base + ISPIF_INTF_CMD_ADDR);
+ uint8_t mask = intfmask, intfnum = 0;
+ uint32_t cid_mask = 0;
+ while (mask != 0) {
+ if (!(intfmask & (0x1 << intfnum))) {
+ mask >>= 1;
+ intfnum++;
+ continue;
}
- vc++;
- cid_mask >>= 4;
+
+ cid_mask = msm_ispif_get_cid_mask(intfnum);
+ vc = 0;
+
+ while (cid_mask != 0) {
+ if ((cid_mask & 0xf) != 0x0) {
+ val = (intf_cmd_mask>>(vc*2)) & 0x3;
+ global_intf_cmd_mask |=
+ (0x3 << ((vc * 2) + (intfnum * 8)));
+ global_intf_cmd_mask &= ~((0x3 & ~val)
+ << ((vc * 2) +
+ (intfnum * 8)));
+ }
+ vc++;
+ cid_mask >>= 4;
+ }
+ mask >>= 1;
+ intfnum++;
}
+ msm_io_w(global_intf_cmd_mask, ispif->base + ISPIF_INTF_CMD_ADDR);
}
-static int msm_ispif_abort_intf_transfer(uint8_t intf)
+static int msm_ispif_abort_intf_transfer(uint8_t intfmask)
{
int rc = 0;
uint8_t intf_cmd_mask = 0xAA;
-
- CDBG("abort stream request\n");
+ uint8_t intfnum = 0, mask = intfmask;
mutex_lock(&ispif->mutex);
- msm_ispif_intf_cmd(intf, intf_cmd_mask);
- rc = msm_ispif_intf_reset(intf);
- global_intf_cmd_mask |= 0xFF<<(intf * 8);
+ msm_ispif_intf_cmd(intfmask, intf_cmd_mask);
+ while (mask != 0) {
+ if (intfmask & (0x1 << intfnum))
+ global_intf_cmd_mask |= (0xFF << (intfnum * 8));
+ mask >>= 1;
+ intfnum++;
+ }
mutex_unlock(&ispif->mutex);
return rc;
}
-static int msm_ispif_start_intf_transfer(uint8_t intf)
+static int msm_ispif_start_intf_transfer(uint8_t intfmask)
{
- uint32_t data;
uint8_t intf_cmd_mask = 0x55;
int rc = 0;
-
- CDBG("start stream request\n");
mutex_lock(&ispif->mutex);
- switch (intf) {
- case PIX0:
- data = msm_io_r(ispif->base + ISPIF_PIX_STATUS_ADDR);
- if ((data & 0xf) != 0xf) {
- CDBG("interface is busy\n");
- mutex_unlock(&ispif->mutex);
- return -EBUSY;
- }
- break;
-
- case RDI0:
- data = msm_io_r(ispif->base + ISPIF_RDI_STATUS_ADDR);
- ispif->start_ack_pending = 1;
- break;
-
- case RDI1:
- data = msm_io_r(ispif->base + ISPIF_RDI_1_STATUS_ADDR);
- ispif->start_ack_pending = 1;
- break;
- }
- msm_ispif_intf_cmd(intf, intf_cmd_mask);
+ rc = msm_ispif_intf_reset(intfmask);
+ msm_ispif_intf_cmd(intfmask, intf_cmd_mask);
mutex_unlock(&ispif->mutex);
return rc;
}
-static int msm_ispif_stop_intf_transfer(uint8_t intf)
+static int msm_ispif_stop_intf_transfer(uint8_t intfmask)
{
int rc = 0;
uint8_t intf_cmd_mask = 0x00;
- CDBG("stop stream request\n");
+ uint8_t intfnum = 0, mask = intfmask;
mutex_lock(&ispif->mutex);
- msm_ispif_intf_cmd(intf, intf_cmd_mask);
- switch (intf) {
- case PIX0:
- while ((msm_io_r(ispif->base + ISPIF_PIX_STATUS_ADDR)
- & 0xf) != 0xf) {
- CDBG("Wait for Idle\n");
- }
- break;
+ msm_ispif_intf_cmd(intfmask, intf_cmd_mask);
+ while (mask != 0) {
+ if (intfmask & (0x1 << intfnum)) {
+ switch (intfnum) {
+ case PIX0:
+ while ((msm_io_r(ispif->base +
+ ISPIF_PIX_STATUS_ADDR)
+ & 0xf) != 0xf) {
+ CDBG("Wait for pix0 Idle\n");
+ }
+ break;
- case RDI0:
- while ((msm_io_r(ispif->base + ISPIF_RDI_STATUS_ADDR)
- & 0xf) != 0xf) {
- CDBG("Wait for Idle\n");
+ case RDI0:
+ while ((msm_io_r(ispif->base +
+ ISPIF_RDI_STATUS_ADDR)
+ & 0xf) != 0xf) {
+ CDBG("Wait for rdi0 Idle\n");
+ }
+ break;
+
+ case RDI1:
+ while ((msm_io_r(ispif->base +
+ ISPIF_RDI_1_STATUS_ADDR)
+ & 0xf) != 0xf) {
+ CDBG("Wait for rdi1 Idle\n");
+ }
+ break;
+
+ default:
+ break;
+ }
+ global_intf_cmd_mask |= (0xFF << (intfnum * 8));
}
- break;
- default:
- break;
+ mask >>= 1;
+ intfnum++;
}
- global_intf_cmd_mask |= 0xFF<<(intf * 8);
mutex_unlock(&ispif->mutex);
return rc;
}
@@ -364,10 +387,77 @@
return rc;
}
+static void ispif_do_tasklet(unsigned long data)
+{
+ unsigned long flags;
+
+ struct ispif_isr_queue_cmd *qcmd = NULL;
+ CDBG("=== ispif_do_tasklet start ===\n");
+
+ while (atomic_read(&ispif_irq_cnt)) {
+ spin_lock_irqsave(&ispif_tasklet_lock, flags);
+ qcmd = list_first_entry(&ispif_tasklet_q,
+ struct ispif_isr_queue_cmd, list);
+ atomic_sub(1, &ispif_irq_cnt);
+
+ if (!qcmd) {
+ spin_unlock_irqrestore(&ispif_tasklet_lock,
+ flags);
+ return;
+ }
+ list_del(&qcmd->list);
+ spin_unlock_irqrestore(&ispif_tasklet_lock,
+ flags);
+ if (qcmd->ispifInterruptStatus0 &
+ ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
+ CDBG("ispif rdi irq status\n");
+ }
+ if (qcmd->ispifInterruptStatus1 &
+ ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
+ CDBG("ispif rdi1 irq status\n");
+ }
+ kfree(qcmd);
+ }
+ CDBG("=== ispif_do_tasklet end ===\n");
+}
+
+DECLARE_TASKLET(ispif_tasklet, ispif_do_tasklet, 0);
+
+static void ispif_process_irq(struct ispif_irq_status *out)
+{
+ unsigned long flags;
+ struct ispif_isr_queue_cmd *qcmd;
+
+ CDBG("ispif_process_irq\n");
+ qcmd = kzalloc(sizeof(struct ispif_isr_queue_cmd),
+ GFP_ATOMIC);
+ if (!qcmd) {
+ pr_err("ispif_process_irq: qcmd malloc failed!\n");
+ return;
+ }
+ qcmd->ispifInterruptStatus0 = out->ispifIrqStatus0;
+ qcmd->ispifInterruptStatus1 = out->ispifIrqStatus1;
+
+ spin_lock_irqsave(&ispif_tasklet_lock, flags);
+ list_add_tail(&qcmd->list, &ispif_tasklet_q);
+
+ atomic_add(1, &ispif_irq_cnt);
+ spin_unlock_irqrestore(&ispif_tasklet_lock, flags);
+ tasklet_schedule(&ispif_tasklet);
+ return;
+}
+
static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out)
{
out->ispifIrqStatus0 = msm_io_r(ispif->base +
- ISPIF_IRQ_STATUS_ADDR);
+ ISPIF_IRQ_STATUS_ADDR);
+ out->ispifIrqStatus1 = msm_io_r(ispif->base +
+ ISPIF_IRQ_STATUS_1_ADDR);
+ msm_io_w(out->ispifIrqStatus0,
+ ispif->base + ISPIF_IRQ_CLEAR_ADDR);
+ msm_io_w(out->ispifIrqStatus1,
+ ispif->base + ISPIF_IRQ_CLEAR_1_ADDR);
+
CDBG("ispif->irq: Irq_status0 = 0x%x\n",
out->ispifIrqStatus0);
if (out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) {
@@ -377,23 +467,14 @@
pr_err("%s: pix intf 0 overflow.\n", __func__);
if (out->ispifIrqStatus0 & (0x1 << RAW_INTF_0_OVERFLOW_IRQ))
pr_err("%s: rdi intf 0 overflow.\n", __func__);
- if (out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
- if (ispif->start_ack_pending) {
- v4l2_subdev_notify(&ispif->subdev,
- NOTIFY_ISP_MSG_EVT,
- (void *)MSG_ID_START_ACK);
- ispif->start_ack_pending = 0;
- /* stop stream at frame boundary */
- msm_ispif_stop_intf_transfer(RDI0);
- }
- v4l2_subdev_notify(&ispif->subdev, NOTIFY_ISP_MSG_EVT,
- (void *)MSG_ID_SOF_ACK);
+ if ((out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_RDI_SOF_MASK) ||
+ (out->ispifIrqStatus1 &
+ ISPIF_IRQ_STATUS_RDI_SOF_MASK)) {
+ ispif_process_irq(out);
}
}
- msm_io_w(out->ispifIrqStatus0,
- ispif->base + ISPIF_IRQ_CLEAR_ADDR);
msm_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
- ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+ ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
}
static irqreturn_t msm_io_ispif_irq(int irq_num, void *data)
@@ -414,6 +495,8 @@
static int msm_ispif_init(const uint32_t *csid_version)
{
int rc = 0;
+ spin_lock_init(&ispif_tasklet_lock);
+ INIT_LIST_HEAD(&ispif_tasklet_q);
rc = request_irq(ispif->irq->start, msm_io_ispif_irq,
IRQF_TRIGGER_RISING, "ispif", 0);
@@ -451,6 +534,7 @@
CDBG("%s, free_irq\n", __func__);
free_irq(ispif->irq->start, 0);
+ tasklet_kill(&ispif_tasklet);
}
void msm_ispif_vfe_get_cid(uint8_t intftype, char *cids, int *num)
diff --git a/drivers/media/video/msm/csi/msm_ispif.h b/drivers/media/video/msm/csi/msm_ispif.h
index deadc28..8f1dd12 100644
--- a/drivers/media/video/msm/csi/msm_ispif.h
+++ b/drivers/media/video/msm/csi/msm_ispif.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
@@ -36,6 +36,12 @@
struct clk *ispif_clk[5];
};
+struct ispif_isr_queue_cmd {
+ struct list_head list;
+ uint32_t ispifInterruptStatus0;
+ uint32_t ispifInterruptStatus1;
+};
+
#define VIDIOC_MSM_ISPIF_CFG \
_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_ispif_params)
@@ -51,6 +57,12 @@
#define ISPIF_OFF_IMMEDIATELY (0x01 << 2)
#define ISPIF_S_STREAM_SHIFT 4
+
+#define PIX_0 (0x01 << 0)
+#define RDI_0 (0x01 << 1)
+#define PIX_1 (0x01 << 2)
+#define RDI_1 (0x01 << 3)
+
void msm_ispif_vfe_get_cid(uint8_t intftype, char *cids, int *num);
#endif
diff --git a/drivers/media/video/msm/io/msm_io_util.c b/drivers/media/video/msm/io/msm_io_util.c
index 0ae247e..207f8be 100644
--- a/drivers/media/video/msm/io/msm_io_util.c
+++ b/drivers/media/video/msm/io/msm_io_util.c
@@ -40,29 +40,42 @@
goto cam_clk_set_err;
}
}
+ rc = clk_prepare(clk_ptr[i]);
+ if (rc < 0) {
+ pr_err("%s prepare failed\n",
+ clk_info[i].clk_name);
+ goto cam_clk_prepare_err;
+ }
+
rc = clk_enable(clk_ptr[i]);
if (rc < 0) {
pr_err("%s enable failed\n",
clk_info[i].clk_name);
- goto cam_clk_set_err;
+ goto cam_clk_enable_err;
}
}
} else {
for (i = num_clk - 1; i >= 0; i--) {
- if (clk_ptr[i] != NULL)
+ if (clk_ptr[i] != NULL) {
clk_disable(clk_ptr[i]);
+ clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
+ }
}
}
return rc;
+cam_clk_enable_err:
+ clk_unprepare(clk_ptr[i]);
+cam_clk_prepare_err:
cam_clk_set_err:
clk_put(clk_ptr[i]);
cam_clk_get_err:
for (i--; i >= 0; i--) {
if (clk_ptr[i] != NULL) {
clk_disable(clk_ptr[i]);
+ clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
}
}
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 22322b8..7cab16e 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -116,6 +116,7 @@
NOTIFY_ISP_MSG_EVT, /* arg = enum ISP_MESSAGE_ID */
NOTIFY_VFE_MSG_OUT, /* arg = struct isp_msg_output */
NOTIFY_VFE_MSG_STATS, /* arg = struct isp_msg_stats */
+ NOTIFY_VFE_MSG_COMP_STATS, /* arg = struct msm_stats_buf */
NOTIFY_VFE_BUF_EVT, /* arg = struct msm_vfe_resp */
NOTIFY_ISPIF_STREAM, /* arg = enable parameter for s_stream */
NOTIFY_VPE_MSG_EVT,
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 6b3aef7..0cffbbf 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -307,6 +307,36 @@
}
}
break;
+ case NOTIFY_VFE_MSG_COMP_STATS: {
+ struct msm_stats_buf *stats = (struct msm_stats_buf *)arg;
+ struct msm_stats_buf *stats_buf = NULL;
+
+ isp_event->isp_data.isp_msg.msg_id = MSG_ID_STATS_COMPOSITE;
+ stats->aec.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->aec.buff, &(stats->aec.fd));
+ stats->awb.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->awb.buff, &(stats->awb.fd));
+ stats->af.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->af.buff, &(stats->af.fd));
+ stats->ihist.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->ihist.buff, &(stats->ihist.fd));
+ stats->rs.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->rs.buff, &(stats->rs.fd));
+ stats->cs.buff = msm_pmem_stats_ptov_lookup(&pmctl->sync,
+ stats->cs.buff, &(stats->cs.fd));
+
+ stats_buf = kmalloc(sizeof(struct msm_stats_buf), GFP_ATOMIC);
+ if (!stats_buf) {
+ pr_err("%s: out of memory.\n", __func__);
+ rc = -ENOMEM;
+ } else {
+ *stats_buf = *stats;
+ isp_event->isp_data.isp_msg.len =
+ sizeof(struct msm_stats_buf);
+ isp_event->isp_data.isp_msg.data = stats_buf;
+ }
+ }
+ break;
case NOTIFY_VFE_MSG_STATS: {
struct msm_stats_buf stats;
struct isp_msg_stats *isp_stats = (struct isp_msg_stats *)arg;
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 2c4fbe4..13d1daf 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -241,6 +241,7 @@
case NOTIFY_ISP_MSG_EVT:
case NOTIFY_VFE_MSG_OUT:
case NOTIFY_VFE_MSG_STATS:
+ case NOTIFY_VFE_MSG_COMP_STATS:
case NOTIFY_VFE_BUF_EVT:
case NOTIFY_VFE_BUF_FREE_EVT:
if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_notify) {
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 4b86bd8..e1a36a8 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -589,6 +589,7 @@
vfe32_ctrl->operation_mode = *p;
vfe32_ctrl->stats_comp = *(++p);
+ vfe32_ctrl->hfr_mode = *(++p);
msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_CFG);
msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_MODULE_CFG);
@@ -684,10 +685,16 @@
static void vfe32_start_common(void)
{
+ uint32_t irq_mask = 0x00E00021;
vfe32_ctrl->start_ack_pending = TRUE;
CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
vfe32_ctrl->operation_mode, vfe32_ctrl->outpath.output_mode);
- msm_io_w(0x00EFE021, vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
+ if (vfe32_ctrl->stats_comp)
+ irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
+ else
+ irq_mask |= 0x000FE000;
+
+ msm_io_w(irq_mask, vfe32_ctrl->vfebase + VFE_IRQ_MASK_0);
msm_io_w(VFE_IMASK_WHILE_STOPPING_1,
vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
@@ -2389,47 +2396,73 @@
static void vfe32_stats_af_ack(struct vfe_cmd_stats_ack *pAck)
{
unsigned long flags;
- spin_lock_irqsave(&vfe32_ctrl->af_ack_lock, flags);
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->af_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->afStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->afStatsControl.ackPending = FALSE;
- spin_unlock_irqrestore(&vfe32_ctrl->af_ack_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
}
static void vfe32_stats_awb_ack(struct vfe_cmd_stats_ack *pAck)
{
unsigned long flags;
- spin_lock_irqsave(&vfe32_ctrl->awb_ack_lock, flags);
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->awb_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->awbStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->awbStatsControl.ackPending = FALSE;
- spin_unlock_irqrestore(&vfe32_ctrl->awb_ack_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
}
static void vfe32_stats_aec_ack(struct vfe_cmd_stats_ack *pAck)
{
unsigned long flags;
- spin_lock_irqsave(&vfe32_ctrl->aec_ack_lock, flags);
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->aec_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->aecStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->aecStatsControl.ackPending = FALSE;
- spin_unlock_irqrestore(&vfe32_ctrl->aec_ack_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
}
static void vfe32_stats_ihist_ack(struct vfe_cmd_stats_ack *pAck)
{
+ unsigned long flags;
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->ihist_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->ihistStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->ihistStatsControl.ackPending = FALSE;
+ spin_unlock_irqrestore(lock, flags);
}
static void vfe32_stats_rs_ack(struct vfe_cmd_stats_ack *pAck)
{
+ unsigned long flags;
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->rs_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->rsStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->rsStatsControl.ackPending = FALSE;
+ spin_unlock_irqrestore(lock, flags);
}
static void vfe32_stats_cs_ack(struct vfe_cmd_stats_ack *pAck)
{
+ unsigned long flags;
+ spinlock_t *lock = (vfe32_ctrl->stats_comp ?
+ &vfe32_ctrl->comp_stats_ack_lock :
+ &vfe32_ctrl->cs_ack_lock);
+ spin_lock_irqsave(lock, flags);
vfe32_ctrl->csStatsControl.nextFrameAddrBuf = pAck->nextStatsBuf;
vfe32_ctrl->csStatsControl.ackPending = FALSE;
+ spin_unlock_irqrestore(lock, flags);
}
-
static inline void vfe32_read_irq_status(struct vfe32_irq_status *out)
{
uint32_t *temp;
@@ -2654,6 +2687,13 @@
msm_io_w_mb(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
vfe32_ctrl->vfebase + VFE_CAMIF_COMMAND);
}
+ } /* if raw snapshot mode. */
+ if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
+ (vfe32_ctrl->operation_mode == VFE_MODE_OF_OPERATION_VIDEO) &&
+ (vfe32_ctrl->vfeFrameId % vfe32_ctrl->hfr_mode != 0)) {
+ vfe32_ctrl->vfeFrameId++;
+ CDBG("Skip the SOF notification when HFR enabled\n");
+ return;
}
vfe32_ctrl->vfeFrameId++;
vfe32_send_isp_msg(vfe32_ctrl, MSG_ID_SOF_ACK);
@@ -2907,11 +2947,6 @@
}
}
-static void vfe32_process_stats_comb_irq(uint32_t *irqstatus)
-{
- return;
-}
-
static uint32_t vfe32_process_stats_irq_common(uint32_t statsNum,
uint32_t newAddr) {
@@ -2971,17 +3006,23 @@
case statsIhistNum: {
msgStats.id = MSG_ID_STATS_IHIST;
+ spin_lock_irqsave(&vfe32_ctrl->ihist_ack_lock, flags);
vfe32_ctrl->ihistStatsControl.ackPending = TRUE;
+ spin_unlock_irqrestore(&vfe32_ctrl->ihist_ack_lock, flags);
}
break;
case statsRsNum: {
msgStats.id = MSG_ID_STATS_RS;
+ spin_lock_irqsave(&vfe32_ctrl->rs_ack_lock, flags);
vfe32_ctrl->rsStatsControl.ackPending = TRUE;
+ spin_unlock_irqrestore(&vfe32_ctrl->rs_ack_lock, flags);
}
break;
case statsCsNum: {
msgStats.id = MSG_ID_STATS_CS;
+ spin_lock_irqsave(&vfe32_ctrl->cs_ack_lock, flags);
vfe32_ctrl->csStatsControl.ackPending = TRUE;
+ spin_unlock_irqrestore(&vfe32_ctrl->cs_ack_lock, flags);
}
break;
@@ -2997,6 +3038,30 @@
return;
}
+static void vfe_send_comp_stats_msg(uint32_t status_bits)
+{
+ struct msm_stats_buf msgStats;
+ uint32_t temp;
+
+ msgStats.frame_id = vfe32_ctrl->vfeFrameId;
+ msgStats.status_bits = status_bits;
+
+ msgStats.aec.buff = vfe32_ctrl->aecStatsControl.bufToRender;
+ msgStats.awb.buff = vfe32_ctrl->awbStatsControl.bufToRender;
+ msgStats.af.buff = vfe32_ctrl->afStatsControl.bufToRender;
+
+ msgStats.ihist.buff = vfe32_ctrl->ihistStatsControl.bufToRender;
+ msgStats.rs.buff = vfe32_ctrl->rsStatsControl.bufToRender;
+ msgStats.cs.buff = vfe32_ctrl->csStatsControl.bufToRender;
+
+ temp = msm_io_r(vfe32_ctrl->vfebase + VFE_STATS_AWB_SGW_CFG);
+ msgStats.awb_ymin = (0xFF00 & temp) >> 8;
+
+ v4l2_subdev_notify(&vfe32_ctrl->subdev,
+ NOTIFY_VFE_MSG_COMP_STATS,
+ &msgStats);
+}
+
static void vfe32_process_stats_ae_irq(void)
{
unsigned long flags;
@@ -3105,6 +3170,126 @@
}
}
+static void vfe32_process_stats(uint32_t status_bits)
+{
+ unsigned long flags;
+ int32_t process_stats = false;
+ CDBG("%s, stats = 0x%x\n", __func__, status_bits);
+
+ spin_lock_irqsave(&vfe32_ctrl->comp_stats_ack_lock, flags);
+ if (status_bits & VFE_IRQ_STATUS0_STATS_AEC) {
+ if (!vfe32_ctrl->aecStatsControl.ackPending) {
+ vfe32_ctrl->aecStatsControl.ackPending = TRUE;
+ vfe32_ctrl->aecStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsAeNum,
+ vfe32_ctrl->aecStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else{
+ vfe32_ctrl->aecStatsControl.bufToRender = 0;
+ vfe32_ctrl->aecStatsControl.droppedStatsFrameCount++;
+ }
+ } else {
+ vfe32_ctrl->aecStatsControl.bufToRender = 0;
+ }
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_AWB) {
+ if (!vfe32_ctrl->awbStatsControl.ackPending) {
+ vfe32_ctrl->awbStatsControl.ackPending = TRUE;
+ vfe32_ctrl->awbStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsAwbNum,
+ vfe32_ctrl->awbStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else{
+ vfe32_ctrl->awbStatsControl.droppedStatsFrameCount++;
+ vfe32_ctrl->awbStatsControl.bufToRender = 0;
+ }
+ } else {
+ vfe32_ctrl->awbStatsControl.bufToRender = 0;
+ }
+
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_AF) {
+ if (!vfe32_ctrl->afStatsControl.ackPending) {
+ vfe32_ctrl->afStatsControl.ackPending = TRUE;
+ vfe32_ctrl->afStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsAfNum,
+ vfe32_ctrl->afStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else {
+ vfe32_ctrl->afStatsControl.bufToRender = 0;
+ vfe32_ctrl->afStatsControl.droppedStatsFrameCount++;
+ }
+ } else {
+ vfe32_ctrl->afStatsControl.bufToRender = 0;
+ }
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_IHIST) {
+ if (!vfe32_ctrl->ihistStatsControl.ackPending) {
+ vfe32_ctrl->ihistStatsControl.ackPending = TRUE;
+ vfe32_ctrl->ihistStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsIhistNum,
+ vfe32_ctrl->ihistStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else {
+ vfe32_ctrl->ihistStatsControl.droppedStatsFrameCount++;
+ vfe32_ctrl->ihistStatsControl.bufToRender = 0;
+ }
+ } else {
+ vfe32_ctrl->ihistStatsControl.bufToRender = 0;
+ }
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_RS) {
+ if (!vfe32_ctrl->rsStatsControl.ackPending) {
+ vfe32_ctrl->rsStatsControl.ackPending = TRUE;
+ vfe32_ctrl->rsStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsRsNum,
+ vfe32_ctrl->rsStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else {
+ vfe32_ctrl->rsStatsControl.droppedStatsFrameCount++;
+ vfe32_ctrl->rsStatsControl.bufToRender = 0;
+ }
+ } else {
+ vfe32_ctrl->rsStatsControl.bufToRender = 0;
+ }
+
+
+ if (status_bits & VFE_IRQ_STATUS0_STATS_CS) {
+ if (!vfe32_ctrl->csStatsControl.ackPending) {
+ vfe32_ctrl->csStatsControl.ackPending = TRUE;
+ vfe32_ctrl->csStatsControl.bufToRender =
+ vfe32_process_stats_irq_common(statsCsNum,
+ vfe32_ctrl->csStatsControl.nextFrameAddrBuf);
+ process_stats = true;
+ } else {
+ vfe32_ctrl->csStatsControl.droppedStatsFrameCount++;
+ vfe32_ctrl->csStatsControl.bufToRender = 0;
+ }
+ } else {
+ vfe32_ctrl->csStatsControl.bufToRender = 0;
+ }
+
+ spin_unlock_irqrestore(&vfe32_ctrl->comp_stats_ack_lock, flags);
+ if (process_stats)
+ vfe_send_comp_stats_msg(status_bits);
+
+ return;
+}
+
+static void vfe32_process_stats_irq(uint32_t *irqstatus)
+{
+ uint32_t status_bits = VFE_COM_STATUS & *irqstatus;
+
+ if ((vfe32_ctrl->hfr_mode != HFR_MODE_OFF) &&
+ (vfe32_ctrl->vfeFrameId % vfe32_ctrl->hfr_mode != 0)) {
+ CDBG("Skip the stats when HFR enabled\n");
+ return;
+ }
+
+ vfe32_process_stats(status_bits);
+ return;
+}
+
static void vfe32_do_tasklet(unsigned long data)
{
unsigned long flags;
@@ -3191,7 +3376,7 @@
if (qcmd->vfeInterruptStatus0 &
VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK) {
CDBG("Stats composite irq occured.\n");
- vfe32_process_stats_comb_irq(
+ vfe32_process_stats_irq(
&qcmd->vfeInterruptStatus0);
}
} else {
@@ -3618,6 +3803,10 @@
spin_lock_init(&vfe32_ctrl->aec_ack_lock);
spin_lock_init(&vfe32_ctrl->awb_ack_lock);
spin_lock_init(&vfe32_ctrl->af_ack_lock);
+ spin_lock_init(&vfe32_ctrl->ihist_ack_lock);
+ spin_lock_init(&vfe32_ctrl->rs_ack_lock);
+ spin_lock_init(&vfe32_ctrl->cs_ack_lock);
+ spin_lock_init(&vfe32_ctrl->comp_stats_ack_lock);
spin_lock_init(&vfe32_ctrl->sd_notify_lock);
INIT_LIST_HEAD(&vfe32_ctrl->tasklet_q);
@@ -3625,6 +3814,7 @@
vfe32_ctrl->update_rolloff = false;
vfe32_ctrl->update_la = false;
vfe32_ctrl->update_gamma = false;
+ vfe32_ctrl->hfr_mode = HFR_MODE_OFF;
enable_irq(vfe32_ctrl->vfeirq->start);
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index 1adfffd..c511b69 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -168,6 +168,8 @@
#define VFE_AF_PINGPONG_STATUS_BIT 0x100
#define VFE_AWB_PINGPONG_STATUS_BIT 0x200
+#define HFR_MODE_OFF 1
+
enum VFE32_DMI_RAM_SEL {
NO_MEM_SELECTED = 0,
BLACK_LUT_RAM_BANK0 = 0x1,
@@ -220,7 +222,7 @@
#define V32_OUT_CLAMP_OFF 0x00000524
#define V32_OUT_CLAMP_LEN 8
-#define V32_OPERATION_CFG_LEN 32
+#define V32_OPERATION_CFG_LEN 36
#define V32_AXI_OUT_OFF 0x00000038
#define V32_AXI_OUT_LEN 216
@@ -778,6 +780,8 @@
#define VFE32_IMASK_STATS_SKIN_BHIST_BUS_OVFL (0x00000001<<21)
#define VFE32_IMASK_AXI_ERROR (0x00000001<<22)
+#define VFE_COM_STATUS 0x000FE000
+
struct vfe32_output_path {
uint16_t output_mode; /* bitmask */
@@ -864,6 +868,7 @@
#define VFE_CLAMP_MIN 0x00000528
#define VFE_REALIGN_BUF 0x0000052C
#define VFE_STATS_CFG 0x00000530
+#define VFE_STATS_AWB_SGW_CFG 0x00000554
#define VFE_DMI_CFG 0x00000598
#define VFE_DMI_ADDR 0x0000059C
#define VFE_DMI_DATA_LO 0x000005A4
@@ -906,6 +911,10 @@
spinlock_t aec_ack_lock;
spinlock_t awb_ack_lock;
spinlock_t af_ack_lock;
+ spinlock_t ihist_ack_lock;
+ spinlock_t rs_ack_lock;
+ spinlock_t cs_ack_lock;
+ spinlock_t comp_stats_ack_lock;
uint32_t extlen;
void *extdata;
@@ -958,6 +967,7 @@
struct platform_device *pdev;
struct clk *vfe_clk[3];
spinlock_t sd_notify_lock;
+ uint32_t hfr_mode;
};
#define statsAeNum 0
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
index a9b7bc6..33db124 100644
--- a/drivers/media/video/msm/sensors/Makefile
+++ b/drivers/media/video/msm/sensors/Makefile
@@ -9,3 +9,4 @@
obj-$(CONFIG_S5K4E1) += s5k4e1_v4l2.o
obj-$(CONFIG_MT9E013) += mt9e013_v4l2.o
obj-$(CONFIG_WEBCAM_OV9726) += ov9726_v4l2.o
+obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 2c296618..d0b4f1f 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -215,7 +215,7 @@
v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
- PIX0, ISPIF_OFF_IMMEDIATELY));
+ PIX_0, ISPIF_OFF_IMMEDIATELY));
s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
msleep(30);
if (update_type == MSM_SENSOR_REG_INIT) {
@@ -244,7 +244,7 @@
output_settings[res].op_pixel_clk);
v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
- PIX0, ISPIF_ON_FRAME_BOUNDARY));
+ PIX_0, ISPIF_ON_FRAME_BOUNDARY));
s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
msleep(30);
}
@@ -502,6 +502,7 @@
goto enable_clk_failed;
}
+ usleep_range(1000, 2000);
if (data->sensor_platform_info->ext_power_ctrl != NULL)
data->sensor_platform_info->ext_power_ctrl(1);
diff --git a/drivers/media/video/msm/sensors/s5k3l1yx.c b/drivers/media/video/msm/sensors/s5k3l1yx.c
new file mode 100644
index 0000000..2177991
--- /dev/null
+++ b/drivers/media/video/msm/sensors/s5k3l1yx.c
@@ -0,0 +1,695 @@
+/* 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 "msm_sensor.h"
+#define SENSOR_NAME "s5k3l1yx"
+#define PLATFORM_DRIVER_NAME "msm_camera_s5k3l1yx"
+
+DEFINE_MUTEX(s5k3l1yx_mut);
+static struct msm_sensor_ctrl_t s5k3l1yx_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_start_settings[] = {
+ {0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_stop_settings[] = {
+ {0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_groupon_settings[] = {
+ {0x104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_groupoff_settings[] = {
+ {0x104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_snap_settings[] = {
+ {0x0501, 0x00}, /* compression_algorithim_L(1d) */
+ {0x0112, 0x0A}, /* CCP_data_format_H */
+ {0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+ {0x0306, 0x00}, /* pll_multiplier */
+ {0x0307, 0xA5}, /* pll_multiplier */
+ {0x0202, 0x09}, /* coarse_integration_time */
+ {0x0203, 0x32}, /* coarse_integration_time */
+ {0x0340, 0x0B}, /* frame_length_lines */
+ {0x0341, 0xEC}, /* frame_length_lines */
+ {0x0342, 0x14}, /* line_length_pck */
+ {0x0343, 0xD8}, /* line_length_pck */
+ {0x0344, 0x00}, /* x_addr_start */
+ {0x0345, 0x08}, /* x_addr_start */
+ {0x0346, 0x00}, /* y_addr_start */
+ {0x0347, 0x00}, /* y_addr_start */
+ {0x0348, 0x0F}, /* x_addr_end */
+ {0x0349, 0xA7}, /* x_addr_end */
+ {0x034A, 0x0B}, /* y_addr_end */
+ {0x034B, 0xC7}, /* y_addr_end */
+ {0x034C, 0x0F}, /* x_output_size */
+ {0x034D, 0xA0}, /* x_output_size */
+ {0x034E, 0x0B}, /* y_output_size */
+ {0x034F, 0xC8}, /* y_output_size */
+ {0x0380, 0x00}, /* x_even_inc */
+ {0x0381, 0x01}, /* x_even_inc */
+ {0x0382, 0x00}, /* x_odd_inc */
+ {0x0383, 0x01}, /* x_odd_inc */
+ {0x0384, 0x00}, /* y_even_inc */
+ {0x0385, 0x01}, /* y_even_inc */
+ {0x0386, 0x00}, /* y_odd_inc */
+ {0x0387, 0x01}, /* y_odd_inc */
+ {0x0900, 0x00}, /* binning_mode */
+ {0x0901, 0x22}, /* binning_type */
+ {0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_prev_settings[] = {
+ {0x0501, 0x00}, /* compression_algorithim_L(1d) */
+ {0x0112, 0x0A}, /* CCP_data_format_H */
+ {0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+ {0x0306, 0x00}, /* pll_multiplier */
+ {0x0307, 0xA5}, /* pll_multiplier */
+ {0x0202, 0x06}, /* coarse_integration_time */
+ {0x0203, 0x00}, /* coarse_integration_time */
+ {0x0340, 0x09}, /* frame_length_lines */
+ {0x0341, 0x98}, /* frame_length_lines */
+ {0x0342, 0x11}, /* line_length_pck */
+ {0x0343, 0x80}, /* line_length_pck */
+ {0x0344, 0x00}, /* x_addr_start */
+ {0x0345, 0x18}, /* x_addr_start */
+ {0x0346, 0x00}, /* y_addr_start */
+ {0x0347, 0x00}, /* y_addr_start */
+ {0x0348, 0x0F}, /* x_addr_end */
+ {0x0349, 0x97}, /* x_addr_end */
+ {0x034A, 0x0B}, /* y_addr_end */
+ {0x034B, 0xC7}, /* y_addr_end */
+ {0x034C, 0x07}, /* x_output_size */
+ {0x034D, 0xC0}, /* x_output_size */
+ {0x034E, 0x05}, /* y_output_size */
+ {0x034F, 0xE4}, /* y_output_size */
+ {0x0380, 0x00}, /* x_even_inc */
+ {0x0381, 0x01}, /* x_even_inc */
+ {0x0382, 0x00}, /* x_odd_inc */
+ {0x0383, 0x03}, /* x_odd_inc */
+ {0x0384, 0x00}, /* y_even_inc */
+ {0x0385, 0x01}, /* y_even_inc */
+ {0x0386, 0x00}, /* y_odd_inc */
+ {0x0387, 0x03}, /* y_odd_inc */
+ {0x0900, 0x01}, /* binning_mode */
+ {0x0901, 0x22}, /* binning_type */
+ {0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_video_60fps_settings[] = {
+ {0x0501, 0x00}, /* compression_algorithim_L(1d) */
+ {0x0112, 0x0A}, /* CCP_data_format_H */
+ {0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+ {0x0306, 0x00}, /* pll_multiplier */
+ {0x0307, 0xA5}, /* pll_multiplier */
+ {0x0202, 0x02}, /* coarse_integration_time */
+ {0x0203, 0x1C}, /* coarse_integration_time */
+ {0x0340, 0x03}, /* frame_length_lines */
+ {0x0341, 0xE0}, /* frame_length_lines */
+ {0x0342, 0x14}, /* line_length_pck */
+ {0x0343, 0xD8}, /* line_length_pck */
+ {0x0344, 0x01}, /* x_addr_start */
+ {0x0345, 0x20}, /* x_addr_start */
+ {0x0346, 0x02}, /* y_addr_start */
+ {0x0347, 0x23}, /* y_addr_start */
+ {0x0348, 0x0E}, /* x_addr_end */
+ {0x0349, 0xA0}, /* x_addr_end */
+ {0x034A, 0x09}, /* y_addr_end */
+ {0x034B, 0xA4}, /* y_addr_end */
+ {0x034C, 0x03}, /* x_output_size */
+ {0x034D, 0x60}, /* x_output_size */
+ {0x034E, 0x01}, /* y_output_size */
+ {0x034F, 0xE0}, /* y_output_size */
+ {0x0380, 0x00}, /* x_even_inc */
+ {0x0381, 0x01}, /* x_even_inc */
+ {0x0382, 0x00}, /* x_odd_inc */
+ {0x0383, 0x07}, /* x_odd_inc */
+ {0x0384, 0x00}, /* y_even_inc */
+ {0x0385, 0x01}, /* y_even_inc */
+ {0x0386, 0x00}, /* y_odd_inc */
+ {0x0387, 0x07}, /* y_odd_inc */
+ {0x0900, 0x01}, /* binning_mode */
+ {0x0901, 0x44}, /* binning_type */
+ {0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_video_90fps_settings[] = {
+ {0x0501, 0x00}, /* compression_algorithim_L(1d) */
+ {0x0112, 0x0A}, /* CCP_data_format_H */
+ {0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+ {0x0306, 0x00}, /* pll_multiplier */
+ {0x0307, 0xA5}, /* pll_multiplier */
+ {0x0202, 0x02}, /* coarse_integration_time */
+ {0x0203, 0x1C}, /* coarse_integration_time */
+ {0x0340, 0x02}, /* frame_length_lines */
+ {0x0341, 0x98}, /* frame_length_lines */
+ {0x0342, 0x14}, /* line_length_pck */
+ {0x0343, 0xD8}, /* line_length_pck */
+ {0x0344, 0x01}, /* x_addr_start */
+ {0x0345, 0x20}, /* x_addr_start */
+ {0x0346, 0x02}, /* y_addr_start */
+ {0x0347, 0x23}, /* y_addr_start */
+ {0x0348, 0x0E}, /* x_addr_end */
+ {0x0349, 0xA0}, /* x_addr_end */
+ {0x034A, 0x09}, /* y_addr_end */
+ {0x034B, 0xA4}, /* y_addr_end */
+ {0x034C, 0x03}, /* x_output_size */
+ {0x034D, 0x60}, /* x_output_size */
+ {0x034E, 0x01}, /* y_output_size */
+ {0x034F, 0xE0}, /* y_output_size */
+ {0x0380, 0x00}, /* x_even_inc */
+ {0x0381, 0x01}, /* x_even_inc */
+ {0x0382, 0x00}, /* x_odd_inc */
+ {0x0383, 0x07}, /* x_odd_inc */
+ {0x0384, 0x00}, /* y_even_inc */
+ {0x0385, 0x01}, /* y_even_inc */
+ {0x0386, 0x00}, /* y_odd_inc */
+ {0x0387, 0x07}, /* y_odd_inc */
+ {0x0900, 0x01}, /* binning_mode */
+ {0x0901, 0x44}, /* binning_type */
+ {0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_video_120fps_settings[] = {
+ {0x0501, 0x00}, /* compression_algorithim_L(1d) */
+ {0x0112, 0x0A}, /* CCP_data_format_H */
+ {0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+ {0x0306, 0x00}, /* pll_multiplier */
+ {0x0307, 0xA5}, /* pll_multiplier */
+ {0x0202, 0x02}, /* coarse_integration_time */
+ {0x0203, 0x1C}, /* coarse_integration_time */
+ {0x0340, 0x02}, /* frame_length_lines */
+ {0x0341, 0x0D}, /* frame_length_lines */
+ {0x0342, 0x14}, /* line_length_pck */
+ {0x0343, 0xD8}, /* line_length_pck */
+ {0x0344, 0x01}, /* x_addr_start */
+ {0x0345, 0x20}, /* x_addr_start */
+ {0x0346, 0x02}, /* y_addr_start */
+ {0x0347, 0x23}, /* y_addr_start */
+ {0x0348, 0x0E}, /* x_addr_end */
+ {0x0349, 0xA0}, /* x_addr_end */
+ {0x034A, 0x09}, /* y_addr_end */
+ {0x034B, 0xA4}, /* y_addr_end */
+ {0x034C, 0x03}, /* x_output_size */
+ {0x034D, 0x60}, /* x_output_size */
+ {0x034E, 0x01}, /* y_output_size */
+ {0x034F, 0xE0}, /* y_output_size */
+ {0x0380, 0x00}, /* x_even_inc */
+ {0x0381, 0x01}, /* x_even_inc */
+ {0x0382, 0x00}, /* x_odd_inc */
+ {0x0383, 0x07}, /* x_odd_inc */
+ {0x0384, 0x00}, /* y_even_inc */
+ {0x0385, 0x01}, /* y_even_inc */
+ {0x0386, 0x00}, /* y_odd_inc */
+ {0x0387, 0x07}, /* y_odd_inc */
+ {0x0900, 0x01}, /* binning_mode */
+ {0x0901, 0x44}, /* binning_type */
+ {0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_dpcm_settings[] = {
+ {0x0501, 0x01}, /* compression_algorithim_L(1d) */
+ {0x0112, 0x0A}, /* CCP_data_format_H */
+ {0x0113, 0x08}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+ {0x0306, 0x00}, /* pll_multiplier */
+ {0x0307, 0xA0}, /* pll_multiplier */
+ {0x0202, 0x09}, /* coarse_integration_time */
+ {0x0203, 0x32}, /* coarse_integration_time */
+ {0x0340, 0x0B}, /* frame_length_lines */
+ {0x0341, 0xEC}, /* frame_length_lines */
+ {0x0342, 0x11}, /* line_length_pck */
+ {0x0343, 0x80}, /* line_length_pck */
+ {0x0344, 0x00}, /* x_addr_start */
+ {0x0345, 0x08}, /* x_addr_start */
+ {0x0346, 0x00}, /* y_addr_start */
+ {0x0347, 0x00}, /* y_addr_start */
+ {0x0348, 0x0F}, /* x_addr_end */
+ {0x0349, 0xA7}, /* x_addr_end */
+ {0x034A, 0x0B}, /* y_addr_end */
+ {0x034B, 0xC7}, /* y_addr_end */
+ {0x034C, 0x0F}, /* x_output_size */
+ {0x034D, 0xA0}, /* x_output_size */
+ {0x034E, 0x0B}, /* y_output_size */
+ {0x034F, 0xC8}, /* y_output_size */
+ {0x0380, 0x00}, /* x_even_inc */
+ {0x0381, 0x01}, /* x_even_inc */
+ {0x0382, 0x00}, /* x_odd_inc */
+ {0x0383, 0x01}, /* x_odd_inc */
+ {0x0384, 0x00}, /* y_even_inc */
+ {0x0385, 0x01}, /* y_even_inc */
+ {0x0386, 0x00}, /* y_odd_inc */
+ {0x0387, 0x01}, /* y_odd_inc */
+ {0x0900, 0x00}, /* binning_mode */
+ {0x0901, 0x22}, /* binning_type */
+ {0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_recommend_settings[] = {
+ {0x0100, 0x00},
+ {0x0103, 0x01}, /* software_reset */
+ {0x0104, 0x00}, /* grouped_parameter_hold */
+ {0x0114, 0x03}, /* CSI_lane_mode, 4 lane setting */
+ {0x0120, 0x00}, /* gain_mode, global analogue gain*/
+ {0x0121, 0x00}, /* exposure_mode, global exposure */
+ {0x0136, 0x18}, /* Extclk_frequency_mhz */
+ {0x0137, 0x00}, /* Extclk_frequency_mhz */
+ {0x0200, 0x08}, /* fine_integration_time */
+ {0x0201, 0x88}, /* fine_integration_time */
+ {0x0204, 0x00}, /* analogue_gain_code_global */
+ {0x0205, 0x20}, /* analogue_gain_code_global */
+ {0x020E, 0x01}, /* digital_gain_greenR */
+ {0x020F, 0x00}, /* digital_gain_greenR */
+ {0x0210, 0x01}, /* digital_gain_red */
+ {0x0211, 0x00}, /* digital_gain_red */
+ {0x0212, 0x01}, /* digital_gain_blue */
+ {0x0213, 0x00}, /* digital_gain_blue */
+ {0x0214, 0x01}, /* digital_gain_greenB */
+ {0x0215, 0x00}, /* digital_gain_greenB */
+ {0x0300, 0x00}, /* vt_pix_clk_div */
+ {0x0301, 0x02}, /* vt_pix_clk_div */
+ {0x0302, 0x00}, /* vt_sys_clk_div */
+ {0x0303, 0x01}, /* vt_sys_clk_div */
+ {0x0304, 0x00}, /* pre_pll_clk_div */
+ {0x0305, 0x06}, /* pre_pll_clk_div */
+ {0x0308, 0x00}, /* op_pix_clk_div */
+ {0x0309, 0x02}, /* op_pix_clk_div */
+ {0x030A, 0x00}, /* op_sys_clk_div */
+ {0x030B, 0x01}, /* op_sys_clk_div */
+ {0x0800, 0x00}, /* tclk_post for D-PHY control */
+ {0x0801, 0x00}, /* ths_prepare for D-PHY control */
+ {0x0802, 0x00}, /* ths_zero_min for D-PHY control */
+ {0x0803, 0x00}, /* ths_trail for D-PHY control */
+ {0x0804, 0x00}, /* tclk_trail_min for D-PHY control */
+ {0x0805, 0x00}, /* tclk_prepare for D-PHY control */
+ {0x0806, 0x00}, /* tclk_zero_zero for D-PHY control */
+ {0x0807, 0x00}, /* tlpx for D-PHY control */
+ {0x0820, 0x02}, /* requested_link_bit_rate_mbps */
+ {0x0821, 0x94}, /* requested_link_bit_rate_mbps */
+ {0x0822, 0x00}, /* requested_link_bit_rate_mbps */
+ {0x0823, 0x00}, /* requested_link_bit_rate_mbps */
+ {0x3000, 0x0A},
+ {0x3001, 0xF7},
+ {0x3002, 0x0A},
+ {0x3003, 0xF7},
+ {0x3004, 0x08},
+ {0x3005, 0xF8},
+ {0x3006, 0x5B},
+ {0x3007, 0x73},
+ {0x3008, 0x49},
+ {0x3009, 0x0C},
+ {0x300A, 0xF8},
+ {0x300B, 0x4E},
+ {0x300C, 0x64},
+ {0x300D, 0x5C},
+ {0x300E, 0x71},
+ {0x300F, 0x0C},
+ {0x3010, 0x6A},
+ {0x3011, 0x14},
+ {0x3012, 0x14},
+ {0x3013, 0x0C},
+ {0x3014, 0x24},
+ {0x3015, 0x4F},
+ {0x3016, 0x86},
+ {0x3017, 0x0E},
+ {0x3018, 0x2C},
+ {0x3019, 0x30},
+ {0x301A, 0x31},
+ {0x301B, 0x32},
+ {0x301C, 0xFF},
+ {0x301D, 0x33},
+ {0x301E, 0x5C},
+ {0x301F, 0xFA},
+ {0x3020, 0x36},
+ {0x3021, 0x46},
+ {0x3022, 0x92},
+ {0x3023, 0xF5},
+ {0x3024, 0x6E},
+ {0x3025, 0x19},
+ {0x3026, 0x32},
+ {0x3027, 0x4B},
+ {0x3028, 0x04},
+ {0x3029, 0x50},
+ {0x302A, 0x0C},
+ {0x302B, 0x04},
+ {0x302C, 0xEF},
+ {0x302D, 0xC1},
+ {0x302E, 0x74},
+ {0x302F, 0x40},
+ {0x3030, 0x00},
+ {0x3031, 0x00},
+ {0x3032, 0x00},
+ {0x3033, 0x00},
+ {0x3034, 0x0F},
+ {0x3035, 0x01},
+ {0x3036, 0x00},
+ {0x3037, 0x00},
+ {0x3038, 0x88},
+ {0x3039, 0x98},
+ {0x303A, 0x1F},
+ {0x303B, 0x01},
+ {0x303C, 0x00},
+ {0x303D, 0x03},
+ {0x303E, 0x2F},
+ {0x303F, 0x09},
+ {0x3040, 0xFF},
+ {0x3041, 0x22},
+ {0x3042, 0x03},
+ {0x3043, 0x03},
+ {0x3044, 0x20},
+ {0x3045, 0x10},
+ {0x3046, 0x10},
+ {0x3047, 0x08},
+ {0x3048, 0x10},
+ {0x3049, 0x01},
+ {0x304A, 0x00},
+ {0x304B, 0x80},
+ {0x304C, 0x80},
+ {0x304D, 0x00},
+ {0x304E, 0x00},
+ {0x304F, 0x00},
+ {0x3051, 0x09},
+ {0x3052, 0xC4},
+ {0x305A, 0xE0},
+ {0x323D, 0x04},
+ {0x323E, 0x38},
+ {0x3305, 0xDD},
+ {0x3050, 0x01},
+ {0x3202, 0x01},
+ {0x3203, 0x01},
+ {0x3204, 0x01},
+ {0x3205, 0x01},
+ {0x3206, 0x01},
+ {0x3207, 0x01},
+ {0x320A, 0x05},
+ {0x320B, 0x20},
+ {0x3235, 0xB7},
+ {0x324C, 0x04},
+ {0x324A, 0x07},
+ {0x3902, 0x01},
+ {0x3915, 0x70},
+ {0x3916, 0x80},
+ {0x3A00, 0x01},
+ {0x3A06, 0x03},
+ {0x3B29, 0x01},
+ {0x3C11, 0x08},
+ {0x3C12, 0x7B},
+ {0x3C13, 0xC0},
+ {0x3C14, 0x70},
+ {0x3C15, 0x80},
+ {0x3C20, 0x00},
+ {0x3C23, 0x03},
+ {0x3C24, 0x00},
+ {0x3C50, 0x72},
+ {0x3C51, 0x85},
+ {0x3C53, 0x40},
+ {0x3C55, 0xA0},
+ {0x3D00, 0x00},
+ {0x3D01, 0x00},
+ {0x3D11, 0x01},
+ {0x3486, 0x05},
+ {0x3B35, 0x06},
+ {0x3A05, 0x01},
+ {0x3A07, 0x2B},
+ {0x3A09, 0x01},
+ {0x3940, 0xFF},
+ {0x3300, 0x00},
+ {0x3900, 0xFF},
+ {0x3914, 0x08},
+ {0x3A01, 0x0F},
+ {0x3A02, 0xA0},
+ {0x3A03, 0x0B},
+ {0x3A04, 0xC8},
+ {0x3701, 0x00},
+ {0x3702, 0x00},
+ {0x3703, 0x00},
+ {0x3704, 0x00},
+ {0x0101, 0x00}, /* image_orientation, mirror & flip off*/
+ {0x0105, 0x01}, /* mask_corrupted_frames */
+ {0x0110, 0x00}, /* CSI-2_channel_identifier */
+ {0x3942, 0x01}, /* [0] 1:mipi, 0:pvi */
+ {0x0B00, 0x00},
+};
+
+static struct v4l2_subdev_info s5k3l1yx_subdev_info[] = {
+ {
+ .code = V4L2_MBUS_FMT_SBGGR10_1X10,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .fmt = 1,
+ .order = 0,
+ },
+ /* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array s5k3l1yx_init_conf[] = {
+ {&s5k3l1yx_recommend_settings[0],
+ ARRAY_SIZE(s5k3l1yx_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array s5k3l1yx_confs[] = {
+ {&s5k3l1yx_snap_settings[0],
+ ARRAY_SIZE(s5k3l1yx_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&s5k3l1yx_prev_settings[0],
+ ARRAY_SIZE(s5k3l1yx_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&s5k3l1yx_video_60fps_settings[0],
+ ARRAY_SIZE(s5k3l1yx_video_60fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&s5k3l1yx_video_90fps_settings[0],
+ ARRAY_SIZE(s5k3l1yx_video_90fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&s5k3l1yx_video_120fps_settings[0],
+ ARRAY_SIZE(s5k3l1yx_video_120fps_settings), 0,
+ MSM_CAMERA_I2C_BYTE_DATA},
+ {&s5k3l1yx_dpcm_settings[0],
+ ARRAY_SIZE(s5k3l1yx_dpcm_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t s5k3l1yx_dimensions[] = {
+ /* 20 fps snapshot */
+ {
+ .x_output = 4000,
+ .y_output = 3016,
+ .line_length_pclk = 5336,
+ .frame_length_lines = 3052,
+ .vt_pixel_clk = 330000000,
+ .op_pixel_clk = 320000000,
+ .binning_factor = 1,
+ },
+ /* 30 fps preview */
+ {
+ .x_output = 1984,
+ .y_output = 1508,
+ .line_length_pclk = 4480,
+ .frame_length_lines = 2456,
+ .vt_pixel_clk = 330000000,
+ .op_pixel_clk = 320000000,
+ .binning_factor = 1,
+ },
+ /* 60 fps video */
+ {
+ .x_output = 864,
+ .y_output = 480,
+ .line_length_pclk = 5336,
+ .frame_length_lines = 992,
+ .vt_pixel_clk = 330000000,
+ .op_pixel_clk = 320000000,
+ .binning_factor = 1,
+ },
+ /* 90 fps video */
+ {
+ .x_output = 864,
+ .y_output = 480,
+ .line_length_pclk = 5336,
+ .frame_length_lines = 664,
+ .vt_pixel_clk = 330000000,
+ .op_pixel_clk = 320000000,
+ .binning_factor = 1,
+ },
+ /* 120 fps video */
+ {
+ .x_output = 864,
+ .y_output = 480,
+ .line_length_pclk = 5336,
+ .frame_length_lines = 525,
+ .vt_pixel_clk = 330000000,
+ .op_pixel_clk = 320000000,
+ .binning_factor = 1,
+ },
+ /* 24 fps snapshot */
+ {
+ .x_output = 4000,
+ .y_output = 3016,
+ .line_length_pclk = 4480,
+ .frame_length_lines = 3052,
+ .vt_pixel_clk = 330000000,
+ .op_pixel_clk = 320000000,
+ .binning_factor = 1,
+ },
+};
+
+static struct msm_camera_csid_vc_cfg s5k3l1yx_cid_cfg[] = {
+ {0, CSI_RAW10, CSI_DECODE_10BIT},
+};
+
+static struct msm_camera_csi2_params s5k3l1yx_csi_params = {
+ .csid_params = {
+ .lane_assign = 0xe4,
+ .lane_cnt = 4,
+ .lut_params = {
+ .num_cid = ARRAY_SIZE(s5k3l1yx_cid_cfg),
+ .vc_cfg = s5k3l1yx_cid_cfg,
+ },
+ },
+ .csiphy_params = {
+ .lane_cnt = 4,
+ .settle_cnt = 0x1B,
+ },
+};
+
+static struct msm_camera_csid_vc_cfg s5k3l1yx_cid_dpcm_cfg[] = {
+ {0, CSI_RAW8, CSI_DECODE_DPCM_10_8_10},
+};
+
+static struct msm_camera_csi2_params s5k3l1yx_csi_dpcm_params = {
+ .csid_params = {
+ .lane_assign = 0xe4,
+ .lane_cnt = 4,
+ .lut_params = {
+ .num_cid = ARRAY_SIZE(s5k3l1yx_cid_dpcm_cfg),
+ .vc_cfg = s5k3l1yx_cid_dpcm_cfg,
+ },
+ },
+ .csiphy_params = {
+ .lane_cnt = 4,
+ .settle_cnt = 0x1B,
+ },
+};
+
+static struct msm_camera_csi2_params *s5k3l1yx_csi_params_array[] = {
+ &s5k3l1yx_csi_params,
+ &s5k3l1yx_csi_params,
+ &s5k3l1yx_csi_params,
+ &s5k3l1yx_csi_params,
+ &s5k3l1yx_csi_params,
+ &s5k3l1yx_csi_dpcm_params,
+};
+
+static struct msm_sensor_output_reg_addr_t s5k3l1yx_reg_addr = {
+ .x_output = 0x34C,
+ .y_output = 0x34E,
+ .line_length_pclk = 0x342,
+ .frame_length_lines = 0x340,
+};
+
+static struct msm_sensor_id_info_t s5k3l1yx_id_info = {
+ .sensor_id_reg_addr = 0x0,
+ .sensor_id = 0x3121,
+};
+
+static struct msm_sensor_exp_gain_info_t s5k3l1yx_exp_gain_info = {
+ .coarse_int_time_addr = 0x202,
+ .global_gain_addr = 0x204,
+ .vert_offset = 8,
+};
+
+static const struct i2c_device_id s5k3l1yx_i2c_id[] = {
+ {SENSOR_NAME, (kernel_ulong_t)&s5k3l1yx_s_ctrl},
+ { }
+};
+
+static struct i2c_driver s5k3l1yx_i2c_driver = {
+ .id_table = s5k3l1yx_i2c_id,
+ .probe = msm_sensor_i2c_probe,
+ .driver = {
+ .name = SENSOR_NAME,
+ },
+};
+
+static struct msm_camera_i2c_client s5k3l1yx_sensor_i2c_client = {
+ .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+ return i2c_add_driver(&s5k3l1yx_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops s5k3l1yx_subdev_core_ops = {
+ .ioctl = msm_sensor_subdev_ioctl,
+ .s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops s5k3l1yx_subdev_video_ops = {
+ .enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops s5k3l1yx_subdev_ops = {
+ .core = &s5k3l1yx_subdev_core_ops,
+ .video = &s5k3l1yx_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t s5k3l1yx_func_tbl = {
+ .sensor_start_stream = msm_sensor_start_stream,
+ .sensor_stop_stream = msm_sensor_stop_stream,
+ .sensor_group_hold_on = msm_sensor_group_hold_on,
+ .sensor_group_hold_off = msm_sensor_group_hold_off,
+ .sensor_set_fps = msm_sensor_set_fps,
+ .sensor_write_exp_gain = msm_sensor_write_exp_gain1,
+ .sensor_write_snapshot_exp_gain = msm_sensor_write_exp_gain1,
+ .sensor_setting = msm_sensor_setting,
+ .sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+ .sensor_mode_init = msm_sensor_mode_init,
+ .sensor_get_output_info = msm_sensor_get_output_info,
+ .sensor_config = msm_sensor_config,
+ .sensor_power_up = msm_sensor_power_up,
+ .sensor_power_down = msm_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t s5k3l1yx_regs = {
+ .default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+ .start_stream_conf = s5k3l1yx_start_settings,
+ .start_stream_conf_size = ARRAY_SIZE(s5k3l1yx_start_settings),
+ .stop_stream_conf = s5k3l1yx_stop_settings,
+ .stop_stream_conf_size = ARRAY_SIZE(s5k3l1yx_stop_settings),
+ .group_hold_on_conf = s5k3l1yx_groupon_settings,
+ .group_hold_on_conf_size = ARRAY_SIZE(s5k3l1yx_groupon_settings),
+ .group_hold_off_conf = s5k3l1yx_groupoff_settings,
+ .group_hold_off_conf_size =
+ ARRAY_SIZE(s5k3l1yx_groupoff_settings),
+ .init_settings = &s5k3l1yx_init_conf[0],
+ .init_size = ARRAY_SIZE(s5k3l1yx_init_conf),
+ .mode_settings = &s5k3l1yx_confs[0],
+ .output_settings = &s5k3l1yx_dimensions[0],
+ .num_conf = ARRAY_SIZE(s5k3l1yx_confs),
+};
+
+static struct msm_sensor_ctrl_t s5k3l1yx_s_ctrl = {
+ .msm_sensor_reg = &s5k3l1yx_regs,
+ .sensor_i2c_client = &s5k3l1yx_sensor_i2c_client,
+ .sensor_i2c_addr = 0x6E,
+ .sensor_output_reg_addr = &s5k3l1yx_reg_addr,
+ .sensor_id_info = &s5k3l1yx_id_info,
+ .sensor_exp_gain_info = &s5k3l1yx_exp_gain_info,
+ .cam_mode = MSM_SENSOR_MODE_INVALID,
+ .csi_params = &s5k3l1yx_csi_params_array[0],
+ .msm_sensor_mutex = &s5k3l1yx_mut,
+ .sensor_i2c_driver = &s5k3l1yx_i2c_driver,
+ .sensor_v4l2_subdev_info = s5k3l1yx_subdev_info,
+ .sensor_v4l2_subdev_info_size = ARRAY_SIZE(s5k3l1yx_subdev_info),
+ .sensor_v4l2_subdev_ops = &s5k3l1yx_subdev_ops,
+ .func_tbl = &s5k3l1yx_func_tbl,
+ .clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Samsung 12MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/pm8038-core.c b/drivers/mfd/pm8038-core.c
index ceb4210..ac57418 100644
--- a/drivers/mfd/pm8038-core.c
+++ b/drivers/mfd/pm8038-core.c
@@ -268,6 +268,11 @@
.id = -1,
};
+static struct mfd_cell leds_cell __devinitdata = {
+ .name = PM8XXX_LEDS_DEV_NAME,
+ .id = -1,
+};
+
static struct mfd_cell debugfs_cell __devinitdata = {
.name = "pm8xxx-debug",
.id = 0,
@@ -501,6 +506,16 @@
}
}
+ if (pdata->leds_pdata) {
+ leds_cell.platform_data = pdata->leds_pdata;
+ leds_cell.pdata_size = sizeof(struct pm8xxx_led_platform_data);
+ ret = mfd_add_devices(pmic->dev, 0, &leds_cell, 1, NULL, 0);
+ if (ret) {
+ pr_err("Failed to add leds subdevice ret=%d\n", ret);
+ goto bail;
+ }
+ }
+
if (pdata->num_regulators > 0 && pdata->regulator_pdatas) {
ret = pm8038_add_regulators(pdata, pmic, irq_base);
if (ret) {
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 7217434..d99f13a 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.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
@@ -41,12 +41,53 @@
struct resource *rx_irq_res;
struct resource *gpios_5wire;
const struct dev_pm_ops *pm_ops;
- int triggered;
- int smd_channel_ready;
+ int triggered;
+ int smd_channel_ready;
+ unsigned int serial_number;
struct wcnss_wlan_config wlan_config;
struct delayed_work wcnss_work;
} *penv = NULL;
+static ssize_t wcnss_serial_number_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (!penv)
+ return -ENODEV;
+
+ return scnprintf(buf, PAGE_SIZE, "%08X\n", penv->serial_number);
+}
+
+static ssize_t wcnss_serial_number_store(struct device *dev,
+ struct device_attribute *attr, const char * buf, size_t count)
+{
+ unsigned int value;
+
+ if (!penv)
+ return -ENODEV;
+
+ if (sscanf(buf, "%08X", &value) != 1)
+ return -EINVAL;
+
+ penv->serial_number = value;
+ return count;
+}
+
+static DEVICE_ATTR(serial_number, S_IRUSR | S_IWUSR,
+ wcnss_serial_number_show, wcnss_serial_number_store);
+
+static int wcnss_create_sysfs(struct device *dev)
+{
+ if (!dev)
+ return -ENODEV;
+ return device_create_file(dev, &dev_attr_serial_number);
+}
+
+static void wcnss_remove_sysfs(struct device *dev)
+{
+ if (dev)
+ device_remove_file(dev, &dev_attr_serial_number);
+}
+
static void wcnss_post_bootup(struct work_struct *work)
{
pr_info("%s: Cancel APPS vote for Iris & Riva\n", __func__);
@@ -189,6 +230,14 @@
}
EXPORT_SYMBOL(wcnss_wlan_unregister_pm_ops);
+unsigned int wcnss_get_serial_number(void)
+{
+ if (penv)
+ return penv->serial_number;
+ return 0;
+}
+EXPORT_SYMBOL(wcnss_get_serial_number);
+
static int wcnss_wlan_suspend(struct device *dev)
{
if (penv && dev && (dev == &penv->pdev->dev) &&
@@ -272,8 +321,14 @@
goto fail_res;
}
+ /* register sysfs entries */
+ ret = wcnss_create_sysfs(&pdev->dev);
+ if (ret)
+ goto fail_sysfs;
+
return 0;
+fail_sysfs:
fail_res:
if (penv->pil)
pil_put(penv->pil);
@@ -360,6 +415,7 @@
static int __devexit
wcnss_wlan_remove(struct platform_device *pdev)
{
+ wcnss_remove_sysfs(&pdev->dev);
return 0;
}
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..0fed092 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.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
@@ -75,6 +75,8 @@
#define SAT_MSG_VER 0x1
#define SAT_MSG_PROT 0x1
#define MSM_SAT_SUCCSS 0x20
+#define MSM_MAX_NSATS 2
+#define MSM_MAX_SATCH 32
#define QC_MFGID_LSB 0x2
#define QC_MFGID_MSB 0x17
@@ -225,7 +227,7 @@
int err;
int ee;
struct completion *wr_comp;
- struct msm_slim_sat *satd;
+ struct msm_slim_sat *satd[MSM_MAX_NSATS];
struct msm_slim_endp pipes[7];
struct msm_slim_sps_bam bam;
struct msm_slim_endp rx_msgq;
@@ -240,6 +242,14 @@
bool reconf_busy;
bool chan_active;
enum msm_ctrl_state state;
+ int nsats;
+};
+
+struct msm_sat_chan {
+ u8 chan;
+ u16 chanh;
+ int req_rem;
+ int req_def;
};
struct msm_slim_sat {
@@ -248,7 +258,7 @@
struct workqueue_struct *wq;
struct work_struct wd;
u8 sat_msgs[SAT_CONCUR_MSG][40];
- u16 *satch;
+ struct msm_sat_chan *satch;
u8 nsatch;
bool sent_capability;
bool pending_reconf;
@@ -258,6 +268,8 @@
spinlock_t lock;
};
+static struct msm_slim_sat *msm_slim_alloc_sat(struct msm_slim_ctrl *dev);
+
static int msm_slim_rx_enqueue(struct msm_slim_ctrl *dev, u32 *buf, u8 len)
{
spin_lock(&dev->rx_lock);
@@ -354,11 +366,28 @@
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
}
+static struct msm_slim_sat *addr_to_sat(struct msm_slim_ctrl *dev, u8 laddr)
+{
+ struct msm_slim_sat *sat = NULL;
+ int i = 0;
+ while (!sat && i < dev->nsats) {
+ if (laddr == dev->satd[i]->satcl.laddr)
+ sat = dev->satd[i];
+ i++;
+ }
+ return sat;
+}
+
static irqreturn_t msm_slim_interrupt(int irq, void *d)
{
struct msm_slim_ctrl *dev = d;
@@ -398,8 +427,13 @@
dev_dbg(dev->dev, "MC: %x, MT: %x\n", mc, mt);
if (mt == SLIM_MSG_MT_DEST_REFERRED_USER ||
mt == SLIM_MSG_MT_SRC_REFERRED_USER) {
- struct msm_slim_sat *sat = dev->satd;
- msm_sat_enqueue(sat, rx_buf, len);
+ u8 laddr = (u8)((rx_buf[0] >> 16) & 0xFF);
+ struct msm_slim_sat *sat = addr_to_sat(dev, laddr);
+ if (sat)
+ msm_sat_enqueue(sat, rx_buf, len);
+ else
+ dev_err(dev->dev, "unknown sat:%d message",
+ laddr);
writel_relaxed(MGR_INT_RX_MSG_RCVD,
dev->base + MGR_INT_CLR);
/*
@@ -407,37 +441,21 @@
* queuing work
*/
mb();
- queue_work(sat->wq, &sat->wd);
+ if (sat)
+ queue_work(sat->wq, &sat->wd);
} else if (mt == SLIM_MSG_MT_CORE &&
mc == SLIM_MSG_MC_REPORT_PRESENT) {
u8 e_addr[6];
msm_get_eaddr(e_addr, rx_buf);
- if (msm_is_sat_dev(e_addr)) {
- /*
- * Consider possibility that this device may
- * be reporting more than once?
- */
- struct msm_slim_sat *sat = dev->satd;
- msm_sat_enqueue(sat, rx_buf, len);
- writel_relaxed(MGR_INT_RX_MSG_RCVD, dev->base +
- MGR_INT_CLR);
- /*
- * Guarantee that CLR bit write goes through
- * before queuing work
- */
- mb();
- queue_work(sat->wq, &sat->wd);
- } else {
- msm_slim_rx_enqueue(dev, rx_buf, len);
- writel_relaxed(MGR_INT_RX_MSG_RCVD, dev->base +
- MGR_INT_CLR);
- /*
- * Guarantee that CLR bit write goes through
- * before signalling completion
- */
- mb();
- complete(&dev->rx_msgq_notify);
- }
+ msm_slim_rx_enqueue(dev, rx_buf, len);
+ writel_relaxed(MGR_INT_RX_MSG_RCVD, dev->base +
+ MGR_INT_CLR);
+ /*
+ * Guarantee that CLR bit write goes through
+ * before signalling completion
+ */
+ mb();
+ complete(&dev->rx_msgq_notify);
} else if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
mc == SLIM_MSG_MC_REPLY_VALUE) {
msm_slim_rx_enqueue(dev, rx_buf, len);
@@ -954,18 +972,67 @@
int i;
int ret = 0;
if (mc == SLIM_USR_MC_CHAN_CTRL) {
- u16 chanh = sat->satch[buf[5]];
+ for (i = 0; i < sat->nsatch; i++) {
+ if (buf[5] == sat->satch[i].chan)
+ break;
+ }
+ if (i >= sat->nsatch)
+ return -ENOTCONN;
oper = ((buf[3] & 0xC0) >> 6);
/* part of grp. activating/removing 1 will take care of rest */
- ret = slim_control_ch(&sat->satcl, chanh, oper, false);
+ ret = slim_control_ch(&sat->satcl, sat->satch[i].chanh, oper,
+ false);
+ if (!ret) {
+ for (i = 5; i < len; i++) {
+ int j;
+ for (j = 0; j < sat->nsatch; j++) {
+ if (buf[i] == sat->satch[j].chan) {
+ if (oper == SLIM_CH_REMOVE)
+ sat->satch[j].req_rem++;
+ else
+ sat->satch[j].req_def++;
+ break;
+ }
+ }
+ }
+ }
} else {
u16 chh[40];
struct slim_ch prop;
u32 exp;
u8 coeff, cc;
u8 prrate = buf[6];
- for (i = 8; i < len; i++)
- chh[i-8] = sat->satch[buf[i]];
+ if (len <= 8)
+ return -EINVAL;
+ for (i = 8; i < len; i++) {
+ int j = 0;
+ for (j = 0; j < sat->nsatch; j++) {
+ if (sat->satch[j].chan == buf[i]) {
+ chh[i - 8] = sat->satch[j].chanh;
+ break;
+ }
+ }
+ if (j < sat->nsatch) {
+ u16 dummy;
+ ret = slim_query_ch(&sat->satcl, buf[i],
+ &dummy);
+ if (ret)
+ return ret;
+ if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
+ sat->satch[j].req_def++;
+ continue;
+ }
+ if (sat->nsatch >= MSM_MAX_SATCH)
+ return -EXFULL;
+ ret = slim_query_ch(&sat->satcl, buf[i], &chh[i - 8]);
+ if (ret)
+ return ret;
+ sat->satch[j].chan = buf[i];
+ sat->satch[j].chanh = chh[i - 8];
+ if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
+ sat->satch[j].req_def++;
+ sat->nsatch++;
+ }
prop.dataf = (enum slim_ch_dataf)((buf[3] & 0xE0) >> 5);
prop.auxf = (enum slim_ch_auxf)((buf[4] & 0xC0) >> 5);
prop.baser = SLIM_RATE_4000HZ;
@@ -981,17 +1048,18 @@
prop.ratem = cc * (1 << exp);
if (i > 9)
ret = slim_define_ch(&sat->satcl, &prop, chh, len - 8,
- true, &sat->satch[buf[8]]);
+ true, &chh[0]);
else
ret = slim_define_ch(&sat->satcl, &prop,
- &sat->satch[buf[8]], 1, false,
- NULL);
+ &chh[0], 1, false, NULL);
dev_dbg(dev->dev, "define sat grp returned:%d", ret);
+ if (ret)
+ return ret;
/* part of group so activating 1 will take care of rest */
if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
ret = slim_control_ch(&sat->satcl,
- sat->satch[buf[8]],
+ chh[0],
SLIM_CH_ACTIVATE, false);
}
return ret;
@@ -1024,6 +1092,18 @@
laddr == (QC_MSM_DEVS - 1))
pm_runtime_enable(dev->dev);
+ if (!ret && msm_is_sat_dev(e_addr)) {
+ struct msm_slim_sat *sat = addr_to_sat(dev,
+ laddr);
+ if (!sat)
+ sat = msm_slim_alloc_sat(dev);
+ if (!sat)
+ return;
+
+ sat->satcl.laddr = laddr;
+ msm_sat_enqueue(sat, (u32 *)buf, len);
+ queue_work(sat->wq, &sat->wd);
+ }
} else if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
mc == SLIM_MSG_MC_REPLY_VALUE) {
u8 tid = buf[3];
@@ -1059,7 +1139,6 @@
while ((msm_sat_dequeue(sat, buf)) != -ENODATA) {
struct slim_msg_txn txn;
- int i;
u8 len, mc, mt;
u32 bw_sl;
int ret = 0;
@@ -1067,6 +1146,7 @@
bool gen_ack = false;
u8 tid;
u8 wbuf[8];
+ int i;
txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER;
txn.dt = SLIM_MSG_DEST_LOGICALADDR;
txn.ec = 0;
@@ -1107,20 +1187,23 @@
continue;
}
/* send a Manager capability msg */
- if (sat->sent_capability)
- continue;
+ if (sat->sent_capability) {
+ if (mt == SLIM_MSG_MT_CORE)
+ goto send_capability;
+ else
+ continue;
+ }
ret = slim_add_device(&dev->ctrl, &sat->satcl);
if (ret) {
dev_err(dev->dev,
"Satellite-init failed");
continue;
}
- /* Satellite owns first 21 channels */
- sat->satch = kzalloc(21 * sizeof(u16), GFP_KERNEL);
- sat->nsatch = 20;
- /* alloc all sat chans */
- for (i = 0; i < 21; i++)
- slim_alloc_ch(&sat->satcl, &sat->satch[i]);
+ /* Satellite-channels */
+ sat->satch = kzalloc(MSM_MAX_SATCH *
+ sizeof(struct msm_sat_chan),
+ GFP_KERNEL);
+send_capability:
txn.mc = SLIM_USR_MC_MASTER_CAPABILITY;
txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER;
txn.la = sat->satcl.laddr;
@@ -1171,6 +1254,20 @@
tid = buf[3];
gen_ack = true;
ret = slim_reconfigure_now(&sat->satcl);
+ for (i = 0; i < sat->nsatch; i++) {
+ struct msm_sat_chan *sch = &sat->satch[i];
+ if (sch->req_rem) {
+ if (!ret)
+ slim_dealloc_ch(&sat->satcl,
+ sch->chanh);
+ sch->req_rem--;
+ } else if (sch->req_def) {
+ if (ret)
+ slim_dealloc_ch(&sat->satcl,
+ sch->chanh);
+ sch->req_def--;
+ }
+ }
if (sat->pending_reconf) {
msm_slim_put_ctrl(dev);
sat->pending_reconf = false;
@@ -1238,6 +1335,44 @@
}
}
+static struct msm_slim_sat *msm_slim_alloc_sat(struct msm_slim_ctrl *dev)
+{
+ struct msm_slim_sat *sat;
+ char *name;
+ if (dev->nsats >= MSM_MAX_NSATS)
+ return NULL;
+
+ sat = kzalloc(sizeof(struct msm_slim_sat), GFP_KERNEL);
+ if (!sat) {
+ dev_err(dev->dev, "no memory for satellite");
+ return NULL;
+ }
+ name = kzalloc(SLIMBUS_NAME_SIZE, GFP_KERNEL);
+ if (!name) {
+ dev_err(dev->dev, "no memory for satellite name");
+ kfree(sat);
+ return NULL;
+ }
+ dev->satd[dev->nsats] = sat;
+ sat->dev = dev;
+ snprintf(name, SLIMBUS_NAME_SIZE, "msm_sat%d", dev->nsats);
+ sat->satcl.name = name;
+ spin_lock_init(&sat->lock);
+ INIT_WORK(&sat->wd, slim_sat_rxprocess);
+ sat->wq = create_singlethread_workqueue(sat->satcl.name);
+ if (!sat->wq) {
+ kfree(name);
+ kfree(sat);
+ return NULL;
+ }
+ /*
+ * Both sats will be allocated from RX thread and RX thread will
+ * process messages sequentially. No synchronization necessary
+ */
+ dev->nsats++;
+ return sat;
+}
+
static void
msm_slim_rx_msgq_event(struct msm_slim_ctrl *dev, struct sps_event_notify *ev)
{
@@ -1370,18 +1505,13 @@
mc = (buffer[0] >> 8) & 0xff;
dev_dbg(dev->dev, "MC: %x, MT: %x\n", mc, mt);
if (mt == SLIM_MSG_MT_DEST_REFERRED_USER ||
- mt == SLIM_MSG_MT_SRC_REFERRED_USER)
- sat = dev->satd;
-
+ mt == SLIM_MSG_MT_SRC_REFERRED_USER) {
+ u8 laddr;
+ laddr = (u8)((buffer[0] >> 16) & 0xff);
+ sat = addr_to_sat(dev, laddr);
+ }
} else if ((index * 4) >= msg_len) {
index = 0;
- if (mt == SLIM_MSG_MT_CORE &&
- mc == SLIM_MSG_MC_REPORT_PRESENT) {
- u8 e_addr[6];
- msm_get_eaddr(e_addr, buffer);
- if (msm_is_sat_dev(e_addr))
- sat = dev->satd;
- }
if (sat) {
msm_sat_enqueue(sat, buffer, msg_len);
queue_work(sat->wq, &sat->wd);
@@ -1751,21 +1881,10 @@
goto err_request_irq_failed;
}
- dev->satd = kzalloc(sizeof(struct msm_slim_sat), GFP_KERNEL);
- if (!dev->satd) {
- ret = -ENOMEM;
- goto err_sat_failed;
- }
-
msm_slim_prg_slew(pdev, dev);
clk_set_rate(dev->rclk, SLIM_ROOT_FREQ);
clk_enable(dev->rclk);
- dev->satd->dev = dev;
- dev->satd->satcl.name = "msm_sat_dev";
- spin_lock_init(&dev->satd->lock);
- INIT_WORK(&dev->satd->wd, slim_sat_rxprocess);
- dev->satd->wq = create_singlethread_workqueue("msm_slim_sat");
/* Component register initialization */
writel_relaxed(1, dev->base + COMP_CFG);
writel_relaxed((EE_MGR_RSC_GRP | EE_NGD_2 | EE_NGD_1),
@@ -1851,8 +1970,6 @@
err_ctrl_failed:
writel_relaxed(0, dev->base + COMP_CFG);
kfree(dev->satd);
-err_sat_failed:
- free_irq(dev->irq, dev);
err_request_irq_failed:
clk_disable(dev->rclk);
clk_put(dev->rclk);
@@ -1877,13 +1994,20 @@
struct resource *bam_mem;
struct resource *slim_mem;
struct resource *slew_mem = dev->slew_mem;
- struct msm_slim_sat *sat = dev->satd;
- slim_remove_device(&sat->satcl);
+ int i;
+ for (i = 0; i < dev->nsats; i++) {
+ struct msm_slim_sat *sat = dev->satd[i];
+ int j;
+ for (j = 0; j < sat->nsatch; j++)
+ slim_dealloc_ch(&sat->satcl, sat->satch[j].chanh);
+ slim_remove_device(&sat->satcl);
+ kfree(sat->satch);
+ destroy_workqueue(sat->wq);
+ kfree(sat->satcl.name);
+ kfree(sat);
+ }
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
- kfree(sat->satch);
- destroy_workqueue(sat->wq);
- kfree(sat);
free_irq(dev->irq, dev);
slim_del_controller(&dev->ctrl);
clk_put(dev->rclk);
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index 69a36af..380ef87 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -755,6 +755,8 @@
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(acm_hs_function);
+ if (!f->hs_descriptors)
+ goto fail;
acm->hs.in = usb_find_endpoint(acm_hs_function,
f->hs_descriptors, &acm_hs_in_desc);
@@ -772,6 +774,11 @@
return 0;
fail:
+ if (f->hs_descriptors)
+ usb_free_descriptors(f->hs_descriptors);
+ if (f->descriptors)
+ usb_free_descriptors(f->descriptors);
+
if (acm->notify_req)
gs_free_req(acm->notify, acm->notify_req);
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index 66cdcb1..aab5b98 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
+#include <linux/debugfs.h>
#include <mach/diag_bridge.h>
#define DRIVER_DESC "USB host diag bridge driver"
@@ -35,6 +36,12 @@
struct kref kref;
struct diag_bridge_ops *ops;
struct platform_device *pdev;
+
+ /* debugging counters */
+ unsigned long bytes_to_host;
+ unsigned long bytes_to_mdm;
+ unsigned pending_reads;
+ unsigned pending_writes;
};
struct diag_bridge *__dev;
@@ -84,6 +91,9 @@
urb->transfer_buffer,
urb->transfer_buffer_length,
urb->status < 0 ? urb->status : urb->actual_length);
+
+ dev->bytes_to_host += urb->actual_length;
+ dev->pending_reads--;
}
int diag_bridge_read(char *data, int size)
@@ -119,10 +129,12 @@
usb_fill_bulk_urb(urb, dev->udev, pipe, data, size,
diag_bridge_read_cb, dev);
usb_anchor_urb(urb, &dev->submitted);
+ dev->pending_reads++;
ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret) {
dev_err(&dev->udev->dev, "submitting urb failed err:%d\n", ret);
+ dev->pending_reads--;
usb_unanchor_urb(urb);
usb_free_urb(urb);
return ret;
@@ -151,6 +163,9 @@
urb->transfer_buffer,
urb->transfer_buffer_length,
urb->status < 0 ? urb->status : urb->actual_length);
+
+ dev->bytes_to_mdm += urb->actual_length;
+ dev->pending_writes--;
}
int diag_bridge_write(char *data, int size)
@@ -186,10 +201,12 @@
usb_fill_bulk_urb(urb, dev->udev, pipe, data, size,
diag_bridge_write_cb, dev);
usb_anchor_urb(urb, &dev->submitted);
+ dev->pending_writes++;
ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret) {
- err("submitting urb failed err:%d", ret);
+ dev_err(&dev->udev->dev, "submitting urb failed err:%d\n", ret);
+ dev->pending_writes--;
usb_unanchor_urb(urb);
usb_free_urb(urb);
return ret;
@@ -211,6 +228,79 @@
kfree(dev);
}
+#if defined(CONFIG_DEBUG_FS)
+#define DEBUG_BUF_SIZE 512
+static ssize_t diag_read_stats(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct diag_bridge *dev = __dev;
+ char *buf;
+ int ret;
+
+ buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ "epin:%d, epout:%d\n"
+ "bytes to host: %lu\n"
+ "bytes to mdm: %lu\n"
+ "pending reads: %u\n"
+ "pending writes: %u\n"
+ "last error: %d\n",
+ dev->in_epAddr, dev->out_epAddr,
+ dev->bytes_to_host, dev->bytes_to_mdm,
+ dev->pending_reads, dev->pending_writes,
+ dev->err);
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t diag_reset_stats(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct diag_bridge *dev = __dev;
+
+ dev->bytes_to_host = dev->bytes_to_mdm = 0;
+ dev->pending_reads = dev->pending_writes = 0;
+
+ return count;
+}
+
+const struct file_operations diag_stats_ops = {
+ .read = diag_read_stats,
+ .write = diag_reset_stats,
+};
+
+static struct dentry *dent;
+
+static void diag_bridge_debugfs_init(void)
+{
+ struct dentry *dfile;
+
+ dent = debugfs_create_dir("diag_bridge", 0);
+ if (IS_ERR(dent))
+ return;
+
+ dfile = debugfs_create_file("status", 0444, dent, 0, &diag_stats_ops);
+ if (!dfile || IS_ERR(dfile))
+ debugfs_remove(dent);
+}
+
+static void diag_bridge_debugfs_cleanup(void)
+{
+ if (dent) {
+ debugfs_remove_recursive(dent);
+ dent = NULL;
+ }
+}
+#else
+static inline void diag_bridge_debugfs_init(void) { }
+static inline void diag_bridge_debugfs_cleanup(void) { }
+#endif
+
static int
diag_bridge_probe(struct usb_interface *ifc, const struct usb_device_id *id)
{
@@ -265,7 +355,7 @@
}
usb_set_intfdata(ifc, dev);
-
+ diag_bridge_debugfs_init();
platform_device_add(dev->pdev);
dev_dbg(&dev->udev->dev, "%s: complete\n", __func__);
@@ -286,6 +376,7 @@
dev_dbg(&dev->udev->dev, "%s:\n", __func__);
platform_device_del(dev->pdev);
+ diag_bridge_debugfs_cleanup();
kref_put(&dev->kref, diag_bridge_delete);
usb_set_intfdata(ifc, NULL);
}
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 00e4fda..6dd65e8 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -42,6 +42,7 @@
#include <mach/clk.h>
#include <mach/msm_xo.h>
+#include <mach/msm_bus.h>
#define MSM_USB_BASE (motg->regs)
#define DRIVER_NAME "msm_otg"
@@ -1122,6 +1123,7 @@
static void msm_otg_start_peripheral(struct otg_transceiver *otg, int on)
{
+ int ret;
struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
struct msm_otg_platform_data *pdata = motg->pdata;
@@ -1142,11 +1144,27 @@
* power collapse(pc) while running in peripheral mode.
*/
otg_pm_qos_update_latency(motg, 1);
+ /* Configure BUS performance parameters for MAX bandwidth */
+ if (motg->bus_perf_client) {
+ ret = msm_bus_scale_client_update_request(
+ motg->bus_perf_client, 1);
+ if (ret)
+ dev_err(motg->otg.dev, "%s: Failed to vote for "
+ "bus bandwidth %d\n", __func__, ret);
+ }
usb_gadget_vbus_connect(otg->gadget);
} else {
dev_dbg(otg->dev, "gadget off\n");
usb_gadget_vbus_disconnect(otg->gadget);
otg_pm_qos_update_latency(motg, 0);
+ /* Configure BUS performance parameters to default */
+ if (motg->bus_perf_client) {
+ ret = msm_bus_scale_client_update_request(
+ motg->bus_perf_client, 0);
+ if (ret)
+ dev_err(motg->otg.dev, "%s: Failed to devote "
+ "for bus bw %d\n", __func__, ret);
+ }
if (pdata->setup_gpio)
pdata->setup_gpio(OTG_STATE_UNDEFINED);
}
@@ -2601,6 +2619,14 @@
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
+ if (motg->pdata->bus_scale_table) {
+ motg->bus_perf_client =
+ msm_bus_scale_register_client(motg->pdata->bus_scale_table);
+ if (!motg->bus_perf_client)
+ dev_err(motg->otg.dev, "%s: Failed to register BUS "
+ "scaling client!!\n", __func__);
+ }
+
return 0;
remove_otg:
@@ -2702,6 +2728,9 @@
if (motg->pdata->swfi_latency)
pm_qos_remove_request(&motg->pm_qos_req_dma);
+ if (motg->bus_perf_client)
+ msm_bus_scale_unregister_client(motg->bus_perf_client);
+
kfree(motg);
return 0;
}
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index f261931..b590c41 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -174,6 +174,10 @@
select FB_MSM_MIPI_DSI
default n
+config FB_MSM_MIPI_DSI_NT35510
+ bool
+ select FB_MSM_MIPI_DSI
+
config FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
bool
select FB_MSM_MIPI_DSI
@@ -286,6 +290,16 @@
select FB_MSM_MIPI_DSI_RENESAS
default n
+config FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT
+ bool
+ select FB_MSM_MIPI_DSI_NT35510
+ default n
+
+config FB_MSM_MIPI_NT35510_CMD_WVGA_PT
+ bool
+ select FB_MSM_MIPI_DSI_NT35510
+ default n
+
config FB_MSM_MIPI_CHIMEI_WXGA
bool "LVDS Chimei WXGA Panel using Toshiba MIPI DSI-to-LVDS bridge."
select FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
@@ -295,6 +309,15 @@
The panel is connected to the host
via Toshiba DSI-to-LVDS bridge.
+config FB_MSM_MIPI_CHIMEI_WUXGA
+ bool "LVDS Chimei WUXGA Panel using Toshiba MIPI DSI-to-LVDS bridge."
+ select FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
+ ---help---
+ Support for Chimei WUXGA (1920x1200) panel.
+ The panel is using a serial LVDS input.
+ The panel is connected to the host
+ via Toshiba DSI-to-LVDS bridge.
+
config FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
bool
select FB_MSM_MIPI_DSI_TRULY
@@ -428,8 +451,11 @@
select FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
select FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
select FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
+ select FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT
+ select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
select FB_MSM_MIPI_SIMULATOR_VIDEO
select FB_MSM_MIPI_CHIMEI_WXGA
+ select FB_MSM_MIPI_CHIMEI_WUXGA
---help---
Support for MIPI panel auto detect
@@ -463,6 +489,8 @@
select FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT
select FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
select FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
+ select FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT
+ select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
select FB_MSM_MIPI_SIMULATOR_VIDEO
---help---
Support for LCDC + MIPI panel auto detect
@@ -525,10 +553,22 @@
bool "MIPI Chimei WXGA PT Panel"
select FB_MSM_MIPI_CHIMEI_WXGA
+config FB_MSM_MIPI_CHIMEI_WUXGA_PANEL
+ bool "MIPI Chimei WUXGA Panel"
+ select FB_MSM_MIPI_CHIMEI_WUXGA
+
config FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT_PANEL
bool "MIPI Truly Video WVGA PT Panel"
select FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
+config FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT_PANEL
+ bool "MIPI NT35510 Video WVGA PT Panel"
+ select FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT
+
+config FB_MSM_MIPI_NT35510_CMD_WVGA_PT_PANEL
+ bool "MIPI NT35510 Command WVGA PT Panel"
+ select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
+
config FB_MSM_MIPI_SIMULATOR_VIDEO_PANEL
bool "MIPI Simulator Video Panel"
select FB_MSM_MIPI_SIMULATOR_VIDEO
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index 2d40b15..bd7628d 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -76,6 +76,7 @@
obj-$(CONFIG_FB_MSM_MIPI_DSI_NOVATEK) += mipi_novatek.o
obj-$(CONFIG_FB_MSM_MIPI_DSI_RENESAS) += mipi_renesas.o
obj-$(CONFIG_FB_MSM_MIPI_DSI_TRULY) += mipi_truly.o
+obj-$(CONFIG_FB_MSM_MIPI_DSI_NT35510) += mipi_NT35510.o
obj-$(CONFIG_FB_MSM_MIPI_DSI_SIMULATOR) += mipi_simulator.o
# MIPI Bridge
@@ -116,7 +117,9 @@
obj-y += mipi_toshiba_video_wvga_pt.o mipi_toshiba_video_wsvga_pt.o
obj-y += mipi_novatek_video_qhd_pt.o mipi_novatek_cmd_qhd_pt.o
obj-y += mipi_renesas_video_fwvga_pt.o mipi_renesas_cmd_fwvga_pt.o
+obj-y += mipi_NT35510_video_wvga_pt.o mipi_NT35510_cmd_wvga_pt.o
obj-y += mipi_chimei_wxga_pt.o
+obj-y += mipi_chimei_wuxga.o
obj-y += mipi_truly_video_wvga_pt.o
else
obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT) += mipi_toshiba_video_wvga_pt.o
@@ -125,9 +128,13 @@
obj-$(CONFIG_FB_MSM_MIPI_NOVATEK_CMD_QHD_PT) += mipi_novatek_cmd_qhd_pt.o
obj-$(CONFIG_FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT) += mipi_renesas_video_fwvga_pt.o
obj-$(CONFIG_FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT) += mipi_renesas_cmd_fwvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT) += mipi_renesas_video_fwvga_pt.o
obj-$(CONFIG_FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT) += mipi_truly_video_wvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_NT35510_CMD_WVGA_PT) += mipi_NT35510_cmd_wvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT) += mipi_NT35510_video_wvga_pt.o
obj-$(CONFIG_FB_MSM_MIPI_SIMULATOR_VIDEO) += mipi_simulator_video.o
obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WXGA) += mipi_chimei_wxga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WUXGA) += mipi_chimei_wuxga.o
endif
obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 512480c..4c443ea 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -468,11 +468,16 @@
int mdp_ppp_pipe_wait(void)
{
int ret = 1;
+ boolean wait;
+ unsigned long flag;
/* wait 5 seconds for the operation to complete before declaring
the MDP hung */
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ wait = mdp_ppp_waiting;
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
- if (mdp_ppp_waiting == TRUE) {
+ if (wait == TRUE) {
ret = wait_for_completion_interruptible_timeout(&mdp_ppp_comp,
5 * HZ);
@@ -548,6 +553,7 @@
void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd)
{
+ unsigned long flag;
/* complete all the writes before starting */
wmb();
@@ -561,7 +567,9 @@
mdp_enable_irq(term);
INIT_COMPLETION(mdp_ppp_comp);
+ spin_lock_irqsave(&mdp_spin_lock, flag);
mdp_ppp_waiting = TRUE;
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
outpdw(MDP_BASE + 0x30, 0x1000);
wait_for_completion_killable(&mdp_ppp_comp);
mdp_disable_irq(term);
@@ -812,128 +820,137 @@
{
uint32 mdp_interrupt = 0;
struct mdp_dma_data *dma;
+ unsigned long flag;
+ /* Ensure all the register write are complete */
+ mb();
mdp_is_in_isr = TRUE;
- do {
- mdp_interrupt = inp32(MDP_INTR_STATUS);
- outp32(MDP_INTR_CLEAR, mdp_interrupt);
- mdp_interrupt &= mdp_intr_mask;
+ mdp_interrupt = inp32(MDP_INTR_STATUS);
+ outp32(MDP_INTR_CLEAR, mdp_interrupt);
- if (mdp_interrupt & TV_ENC_UNDERRUN) {
- mdp_interrupt &= ~(TV_ENC_UNDERRUN);
- mdp_tv_underflow_cnt++;
- }
+ mdp_interrupt &= mdp_intr_mask;
- if (!mdp_interrupt)
- break;
+ if (mdp_interrupt & TV_ENC_UNDERRUN) {
+ mdp_interrupt &= ~(TV_ENC_UNDERRUN);
+ mdp_tv_underflow_cnt++;
+ }
- /* DMA3 TV-Out Start */
- if (mdp_interrupt & TV_OUT_DMA3_START) {
- /* let's disable TV out interrupt */
- mdp_intr_mask &= ~TV_OUT_DMA3_START;
- outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ if (!mdp_interrupt)
+ goto out;
- dma = &dma3_data;
- if (dma->waiting) {
- dma->waiting = FALSE;
- complete(&dma->comp);
- }
- }
-#ifndef CONFIG_FB_MSM_MDP22
- if (mdp_interrupt & MDP_HIST_DONE) {
- outp32(MDP_BASE + 0x94018, 0x3);
- outp32(MDP_INTR_CLEAR, MDP_HIST_DONE);
- complete(&mdp_hist_comp);
- }
+ /* DMA3 TV-Out Start */
+ if (mdp_interrupt & TV_OUT_DMA3_START) {
+ /* let's disable TV out interrupt */
+ mdp_intr_mask &= ~TV_OUT_DMA3_START;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
- /* LCDC UnderFlow */
- if (mdp_interrupt & LCDC_UNDERFLOW) {
- mdp_lcdc_underflow_cnt++;
- /*when underflow happens HW resets all the histogram
- registers that were set before so restore them back
- to normal.*/
- MDP_OUTP(MDP_BASE + 0x94010, 1);
- MDP_OUTP(MDP_BASE + 0x9401c, 2);
- if (mdp_is_hist_start == TRUE) {
- MDP_OUTP(MDP_BASE + 0x94004,
- mdp_hist_frame_cnt);
- MDP_OUTP(MDP_BASE + 0x94000, 1);
- }
- }
- /* LCDC Frame Start */
- if (mdp_interrupt & LCDC_FRAME_START) {
- /* let's disable LCDC interrupt */
- mdp_intr_mask &= ~LCDC_FRAME_START;
- outp32(MDP_INTR_ENABLE, mdp_intr_mask);
-
- dma = &dma2_data;
- if (dma->waiting) {
- dma->waiting = FALSE;
- complete(&dma->comp);
- }
- }
-
- /* DMA2 LCD-Out Complete */
- if (mdp_interrupt & MDP_DMA_S_DONE) {
- dma = &dma_s_data;
- dma->busy = FALSE;
- mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF,
- TRUE);
+ dma = &dma3_data;
+ if (dma->waiting) {
+ dma->waiting = FALSE;
complete(&dma->comp);
}
- /* DMA_E LCD-Out Complete */
- if (mdp_interrupt & MDP_DMA_E_DONE) {
- dma = &dma_s_data;
+ }
+#ifndef CONFIG_FB_MSM_MDP22
+ if (mdp_interrupt & MDP_HIST_DONE) {
+ outp32(MDP_BASE + 0x94018, 0x3);
+ outp32(MDP_INTR_CLEAR, MDP_HIST_DONE);
+ complete(&mdp_hist_comp);
+ }
+
+ /* LCDC UnderFlow */
+ if (mdp_interrupt & LCDC_UNDERFLOW) {
+ mdp_lcdc_underflow_cnt++;
+ /*when underflow happens HW resets all the histogram
+ registers that were set before so restore them back
+ to normal.*/
+ MDP_OUTP(MDP_BASE + 0x94010, 1);
+ MDP_OUTP(MDP_BASE + 0x9401c, 2);
+ if (mdp_is_hist_start == TRUE) {
+ MDP_OUTP(MDP_BASE + 0x94004,
+ mdp_hist_frame_cnt);
+ MDP_OUTP(MDP_BASE + 0x94000, 1);
+ }
+ }
+
+ /* LCDC Frame Start */
+ if (mdp_interrupt & LCDC_FRAME_START) {
+ /* let's disable LCDC interrupt */
+ mdp_intr_mask &= ~LCDC_FRAME_START;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+
+ dma = &dma2_data;
+ if (dma->waiting) {
+ dma->waiting = FALSE;
+ complete(&dma->comp);
+ }
+ }
+
+ /* DMA2 LCD-Out Complete */
+ if (mdp_interrupt & MDP_DMA_S_DONE) {
+ dma = &dma_s_data;
+ dma->busy = FALSE;
+ mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
+ complete(&dma->comp);
+ }
+
+ /* DMA_E LCD-Out Complete */
+ if (mdp_interrupt & MDP_DMA_E_DONE) {
+ dma = &dma_s_data;
+ dma->busy = FALSE;
+ mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
+ complete(&dma->comp);
+ }
+
+#endif
+
+ /* DMA2 LCD-Out Complete */
+ if (mdp_interrupt & MDP_DMA_P_DONE) {
+ struct timeval now;
+
+ mdp_dma2_last_update_time = ktime_sub(ktime_get_real(),
+ mdp_dma2_last_update_time);
+ if (mdp_debug[MDP_DMA2_BLOCK]) {
+ jiffies_to_timeval(jiffies, &now);
+ mdp_dma2_timeval.tv_usec =
+ now.tv_usec - mdp_dma2_timeval.tv_usec;
+ }
+#ifndef CONFIG_FB_MSM_MDP303
+ dma = &dma2_data;
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ dma->busy = FALSE;
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+ mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
+ complete(&dma->comp);
+#else
+ if (mdp_prim_panel_type == MIPI_CMD_PANEL) {
+ dma = &dma2_data;
+ spin_lock_irqsave(&mdp_spin_lock, flag);
dma->busy = FALSE;
- mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_OFF,
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+ mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF,
TRUE);
complete(&dma->comp);
}
-
#endif
+ }
- /* DMA2 LCD-Out Complete */
- if (mdp_interrupt & MDP_DMA_P_DONE) {
- struct timeval now;
-
- mdp_dma2_last_update_time = ktime_sub(ktime_get_real(),
- mdp_dma2_last_update_time);
- if (mdp_debug[MDP_DMA2_BLOCK]) {
- jiffies_to_timeval(jiffies, &now);
- mdp_dma2_timeval.tv_usec =
- now.tv_usec - mdp_dma2_timeval.tv_usec;
- }
-#ifndef CONFIG_FB_MSM_MDP303
- dma = &dma2_data;
- dma->busy = FALSE;
- mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF,
- TRUE);
- complete(&dma->comp);
-#else
- if (mdp_prim_panel_type == MIPI_CMD_PANEL) {
- dma = &dma2_data;
- dma->busy = FALSE;
- mdp_pipe_ctrl(MDP_DMA2_BLOCK,
- MDP_BLOCK_POWER_OFF, TRUE);
- complete(&dma->comp);
- }
-#endif
- }
- /* PPP Complete */
- if (mdp_interrupt & MDP_PPP_DONE) {
+ /* PPP Complete */
+ if (mdp_interrupt & MDP_PPP_DONE) {
#ifdef CONFIG_FB_MSM_MDP31
- MDP_OUTP(MDP_BASE + 0x00100, 0xFFFF);
+ MDP_OUTP(MDP_BASE + 0x00100, 0xFFFF);
#endif
- mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
- if (mdp_ppp_waiting) {
- mdp_ppp_waiting = FALSE;
- complete(&mdp_ppp_comp);
- }
+ mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ if (mdp_ppp_waiting) {
+ mdp_ppp_waiting = FALSE;
+ complete(&mdp_ppp_comp);
}
- } while (1);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+ }
- mdp_is_in_isr = FALSE;
+out:
+mdp_is_in_isr = FALSE;
return IRQ_HANDLED;
}
@@ -1083,12 +1100,12 @@
static int mdp_off(struct platform_device *pdev)
{
int ret = 0;
+
mdp_histogram_ctrl(FALSE);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
ret = panel_next_off(pdev);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
-
return ret;
}
@@ -1098,9 +1115,12 @@
#ifdef CONFIG_FB_MSM_MDP40
struct msm_fb_data_type *mfd;
+ mdp4_overlay_ctrl_db_reset();
+
+ mfd = platform_get_drvdata(pdev);
+
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
if (is_mdp4_hw_reset()) {
- mfd = platform_get_drvdata(pdev);
mdp_vsync_cfg_regs(mfd, FALSE);
mdp4_hw_init();
outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
@@ -1112,6 +1132,14 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
ret = panel_next_on(pdev);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+#ifdef CONFIG_FB_MSM_MDP40
+ if (mfd->panel.type == MIPI_CMD_PANEL)
+ mdp4_dsi_cmd_overlay_restore();
+ else if (mfd->panel.type == MDDI_PANEL)
+ mdp4_mddi_overlay_restore();
+#endif
+
return ret;
}
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 3862823..7b2b2c2 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -513,7 +513,6 @@
void mdp4_overlay1_done_atv(void);
void mdp4_primary_vsync_lcdc(void);
void mdp4_external_vsync_dtv(void);
-void mdp4_mddi_overlay_restore(void);
void mdp4_overlay_lcdc_wait4vsync(struct msm_fb_data_type *mfd);
void mdp4_overlay_lcdc_vsync_push(struct msm_fb_data_type *mfd,
struct mdp4_overlay_pipe *pipe);
@@ -523,11 +522,16 @@
#ifndef CONFIG_FB_MSM_MIPI_DSI
void mdp4_mddi_dma_busy_wait(struct msm_fb_data_type *mfd);
+void mdp4_mddi_overlay_restore(void);
#else
static inline void mdp4_mddi_dma_busy_wait(struct msm_fb_data_type *mfd)
{
/* empty */
}
+static inline void mdp4_mddi_overlay_restore(void)
+{
+ /* empty */
+}
#endif
void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd,
@@ -629,6 +633,7 @@
void mdp4_dsi_blt_dmap_busy_wait(struct msm_fb_data_type *mfd);
void mdp4_overlay_dsi_video_vsync_push(struct msm_fb_data_type *mfd,
struct mdp4_overlay_pipe *pipe);
+void mdp4_dsi_cmd_overlay_restore(void);
#else
static inline void mdp4_dsi_cmd_dma_busy_wait(struct msm_fb_data_type *mfd)
{
@@ -643,6 +648,10 @@
{
/* empty */
}
+static inline void mdp4_dsi_cmd_overlay_restore(void)
+{
+ /* empty */
+}
#endif /* MIPI_DSI */
void mdp4_dsi_cmd_kickoff_ui(struct msm_fb_data_type *mfd,
@@ -651,7 +660,6 @@
struct mdp4_overlay_pipe *pipe);
void mdp4_dsi_cmd_overlay_kickoff(struct msm_fb_data_type *mfd,
struct mdp4_overlay_pipe *pipe);
-void mdp4_dsi_cmd_overlay_restore(void);
void mdp4_overlay_panel_3d(int mixer_num, uint32 panel_3d);
int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req);
@@ -674,6 +682,7 @@
uint32_t mdp4_ss_table_value(int8_t param, int8_t index);
void mdp4_overlay_status_write(enum mdp4_overlay_status type, bool val);
bool mdp4_overlay_status_read(enum mdp4_overlay_status type);
+void mdp4_overlay_ctrl_db_reset(void);
int mdp4_overlay_writeback_on(struct platform_device *pdev);
int mdp4_overlay_writeback_off(struct platform_device *pdev);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 8b61024..bf53c73 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -110,6 +110,14 @@
return overlay_status[type];
}
+void mdp4_overlay_ctrl_db_reset(void)
+{
+ int i;
+
+ for (i = MDP4_MIXER0; i < MDP4_MIXER_MAX; i++)
+ ctrl->mixer_cfg[i] = 0;
+}
+
int mdp4_overlay_mixer_play(int mixer_num)
{
if (mixer_num == MDP4_MIXER2)
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 52a402c..3f12827 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -110,6 +110,8 @@
if (mfd->key != MFD_KEY)
return -EINVAL;
+ mdp4_overlay_ctrl_db_reset();
+
fbi = mfd->fbi;
var = &fbi->var;
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 848e6b9..fdb1ec5 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -160,6 +160,8 @@
if (mfd->key != MFD_KEY)
return -EINVAL;
+ mdp4_overlay_ctrl_db_reset();
+
fbi = mfd->fbi;
var = &fbi->var;
diff --git a/drivers/video/msm/mdp_dma.c b/drivers/video/msm/mdp_dma.c
index f9f7954..3997814 100644
--- a/drivers/video/msm/mdp_dma.c
+++ b/drivers/video/msm/mdp_dma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -478,16 +478,20 @@
void mdp_dma2_update(struct msm_fb_data_type *mfd)
#endif
{
+ unsigned long flag;
+
down(&mfd->dma->mutex);
if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) {
down(&mfd->sem);
mfd->ibuf_flushed = TRUE;
mdp_dma2_update_lcd(mfd);
+ spin_lock_irqsave(&mdp_spin_lock, flag);
mdp_enable_irq(MDP_DMA2_TERM);
mfd->dma->busy = TRUE;
INIT_COMPLETION(mfd->dma->comp);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
/* schedule DMA to start */
mdp_dma_schedule(mfd, MDP_DMA2_TERM);
up(&mfd->sem);
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
index 19dfe82..199e472 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/msm/mdp_ppp.c
@@ -1,7 +1,7 @@
/* drivers/video/msm/src/drv/mdp/mdp_ppp.c
*
* Copyright (C) 2007 Google Incorporated
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-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
@@ -52,6 +52,7 @@
[MDP_RGBX_8888] = 4,
[MDP_Y_CBCR_H2V1] = 1,
[MDP_Y_CBCR_H2V2] = 1,
+ [MDP_Y_CBCR_H2V2_ADRENO] = 1,
[MDP_Y_CRCB_H2V1] = 1,
[MDP_Y_CRCB_H2V2] = 1,
[MDP_YCRYCB_H2V1] = 2,
@@ -535,14 +536,16 @@
#define IS_PSEUDOPLNR(img) ((img == MDP_Y_CRCB_H2V2) | \
(img == MDP_Y_CBCR_H2V2) | \
+ (img == MDP_Y_CBCR_H2V2_ADRENO) | \
(img == MDP_Y_CRCB_H2V1) | \
(img == MDP_Y_CBCR_H2V1))
#define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp)
#define Y_TO_CRCB_RATIO(format) \
- ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CRCB_H2V2) ? 2 :\
- (format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ? 1 : 1)
+ ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CBCR_H2V2_ADRENO || \
+ format == MDP_Y_CRCB_H2V2) ? 2 : (format == MDP_Y_CBCR_H2V1 || \
+ format == MDP_Y_CRCB_H2V1) ? 1 : 1)
#ifdef CONFIG_ANDROID_PMEM
static void get_len(struct mdp_img *img, struct mdp_rect *rect, uint32_t bpp,
@@ -589,6 +592,7 @@
uint32 src_width;
uint32 src_height;
uint32 src0_ystride;
+ uint32 src0_y1stride;
uint32 dst_roi_width;
uint32 dst_roi_height;
uint32 ppp_src_cfg_reg, ppp_operation_reg, ppp_dst_cfg_reg;
@@ -868,6 +872,7 @@
break;
case MDP_Y_CBCR_H2V2:
+ case MDP_Y_CBCR_H2V2_ADRENO:
case MDP_Y_CRCB_H2V2:
inpBpp = 1;
src1 = (uint8 *) iBuf->mdpImg.cbcr_addr;
@@ -1059,7 +1064,16 @@
}
}
- src0_ystride = src_width * inpBpp;
+ if (iBuf->mdpImg.imgType == MDP_Y_CBCR_H2V2_ADRENO)
+ src0_ystride = ALIGN(src_width, 32) * inpBpp;
+ else
+ src0_ystride = src_width * inpBpp;
+
+ if (iBuf->mdpImg.imgType == MDP_Y_CBCR_H2V2_ADRENO)
+ src0_y1stride = 2 * ALIGN(src_width/2, 32);
+ else
+ src0_y1stride = src0_ystride;
+
dest0_ystride = iBuf->ibuf_width * iBuf->bpp;
/* no need to care about rotation since it's the real-XY. */
@@ -1121,7 +1135,7 @@
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x010c, src0); /* comp.plane 0 */
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0110, src1); /* comp.plane 1 */
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x011c,
- (src0_ystride << 16 | src0_ystride));
+ (src0_y1stride << 16 | src0_ystride));
/* setup for rgb 565 */
MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0124, ppp_src_cfg_reg);
@@ -1362,9 +1376,16 @@
iBuf.mdpImg.imgType = req->src.format;
iBuf.mdpImg.bmy_addr = (uint32 *) (src_start + req->src.offset);
- iBuf.mdpImg.cbcr_addr =
- (uint32 *) ((uint32) iBuf.mdpImg.bmy_addr +
- req->src.width * req->src.height);
+
+ if (iBuf.mdpImg.imgType == MDP_Y_CBCR_H2V2_ADRENO)
+ iBuf.mdpImg.cbcr_addr =
+ (uint32 *) ((uint32) iBuf.mdpImg.bmy_addr +
+ ALIGN((ALIGN(req->src.width, 32) *
+ ALIGN(req->src.height, 32)), 4096));
+ else
+ iBuf.mdpImg.cbcr_addr =
+ (uint32 *) ((uint32) iBuf.mdpImg.bmy_addr +
+ req->src.width * req->src.height);
iBuf.mdpImg.mdpOp = MDPOP_NOP;
diff --git a/drivers/video/msm/mdp_ppp_v20.c b/drivers/video/msm/mdp_ppp_v20.c
index 8828a8f..e2a6564 100644
--- a/drivers/video/msm/mdp_ppp_v20.c
+++ b/drivers/video/msm/mdp_ppp_v20.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
@@ -1625,6 +1625,7 @@
* offsite in vertical axis
*/
case MDP_Y_CBCR_H2V2:
+ case MDP_Y_CBCR_H2V2_ADRENO:
case MDP_Y_CRCB_H2V2:
/* floor( luma_interp_point_left / 2) */
chroma_interp_point_left = luma_interp_point_left >> 1;
@@ -1678,6 +1679,7 @@
break;
case MDP_Y_CBCR_H2V2:
+ case MDP_Y_CBCR_H2V2_ADRENO:
case MDP_Y_CRCB_H2V2:
/*
* cosite in horizontal dir, and offsite in vertical dir
diff --git a/drivers/video/msm/mipi_NT35510.c b/drivers/video/msm/mipi_NT35510.c
new file mode 100644
index 0000000..ff513d0
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35510.c
@@ -0,0 +1,586 @@
+/* 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 "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_NT35510.h"
+
+static struct msm_panel_common_pdata *mipi_nt35510_pdata;
+static struct dsi_buf nt35510_tx_buf;
+static struct dsi_buf nt35510_rx_buf;
+
+#define NT35510_SLEEP_OFF_DELAY 150
+#define NT35510_DISPLAY_ON_DELAY 150
+
+/* common setting */
+static char exit_sleep[2] = {0x11, 0x00};
+static char display_on[2] = {0x29, 0x00};
+static char display_off[2] = {0x28, 0x00};
+static char enter_sleep[2] = {0x10, 0x00};
+static char write_ram[2] = {0x2c, 0x00}; /* write ram */
+
+static struct dsi_cmd_desc nt35510_display_off_cmds[] = {
+ {DTYPE_DCS_WRITE, 1, 0, 0, 150, sizeof(display_off), display_off},
+ {DTYPE_DCS_WRITE, 1, 0, 0, 150, sizeof(enter_sleep), enter_sleep}
+};
+
+static char cmd0[6] = {
+ 0xF0, 0x55, 0xAA, 0x52,
+ 0x08, 0x01,
+};
+static char cmd1[4] = {
+ 0xBC, 0x00, 0xA0, 0x00,
+};
+static char cmd2[4] = {
+ 0xBD, 0x00, 0xA0, 0x00,
+};
+static char cmd3[3] = {
+ 0xBE, 0x00, 0x79,
+};
+static char cmd4[53] = {
+ 0xD1, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char cmd5[53] = {
+ 0xD2, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char cmd6[53] = {
+ 0xD3, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char cmd7[53] = {
+ 0xD4, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char cmd8[53] = {
+ 0xD5, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char cmd9[53] = {
+ 0xD6, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char cmd10[4] = {
+ 0xB0, 0x0A, 0x0A, 0x0A,
+};
+static char cmd11[4] = {
+ 0xB1, 0x0A, 0x0A, 0x0A,
+};
+static char cmd12[4] = {
+ 0xBA, 0x24, 0x24, 0x24,
+};
+static char cmd13[4] = {
+ 0xB9, 0x24, 0x24, 0x24,
+};
+static char cmd14[4] = {
+ 0xB8, 0x24, 0x24, 0x24,
+};
+static char cmd15[6] = {
+ 0xF0, 0x55, 0xAA, 0x52,
+ 0x08, 0x00,
+};
+static char cmd16[2] = {
+ 0xB3, 0x00,
+};
+static char cmd17[2] = {
+ 0xB4, 0x10,
+};
+static char cmd18[2] = {
+ 0xB6, 0x02,
+};
+static char cmd19[3] = {
+ 0xB1, 0xEC, 0x06,
+};
+static char cmd20[4] = {
+ 0xBC, 0x05, 0x05, 0x05,
+};
+static char cmd21[3] = {
+ 0xB7, 0x20, 0x20,
+};
+static char cmd22[5] = {
+ 0xB8, 0x01, 0x03, 0x03,
+ 0x03,
+};
+static char cmd23[19] = {
+ 0xC8, 0x01, 0x00, 0x78,
+ 0x50, 0x78, 0x50, 0x78,
+ 0x50, 0x78, 0x50, 0xC8,
+ 0x3C, 0x3C, 0xC8, 0xC8,
+ 0x3C, 0x3C, 0xC8,
+};
+static char cmd24[6] = {
+ 0xBD, 0x01, 0x84, 0x07,
+ 0x31, 0x00,
+};
+static char cmd25[6] = {
+ 0xBE, 0x01, 0x84, 0x07,
+ 0x31, 0x00,
+};
+static char cmd26[6] = {
+ 0xBF, 0x01, 0x84, 0x07,
+ 0x31, 0x00,
+};
+static char cmd27[2] = {
+ 0x35, 0x00,
+};
+static char config_MADCTL[2] = {0x36, 0xC0};
+static struct dsi_cmd_desc nt35510_cmd_display_on_cmds[] = {
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd0), cmd0},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd1), cmd1},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd2), cmd2},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd3), cmd3},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd4), cmd4},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd5), cmd5},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd6), cmd6},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd7), cmd7},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd8), cmd8},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd9), cmd9},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd10), cmd10},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd11), cmd11},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd12), cmd12},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd13), cmd13},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd14), cmd14},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd15), cmd15},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd16), cmd16},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd17), cmd17},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd18), cmd18},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd19), cmd19},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd20), cmd20},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd21), cmd21},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd22), cmd22},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd23), cmd23},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd24), cmd24},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd25), cmd25},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd26), cmd26},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd27), cmd27},
+
+ {DTYPE_DCS_WRITE, 1, 0, 0, 150, sizeof(exit_sleep), exit_sleep},
+ {DTYPE_DCS_WRITE, 1, 0, 0, 10, sizeof(display_on), display_on},
+
+ {DTYPE_DCS_WRITE1, 1, 0, 0, 150,
+ sizeof(config_MADCTL), config_MADCTL},
+
+ {DTYPE_DCS_WRITE, 1, 0, 0, 10, sizeof(write_ram), write_ram},
+};
+
+static char video0[6] = {
+ 0xF0, 0x55, 0xAA, 0x52,
+ 0x08, 0x01,
+};
+static char video1[4] = {
+ 0xBC, 0x00, 0xA0, 0x00,
+};
+static char video2[4] = {
+ 0xBD, 0x00, 0xA0, 0x00,
+};
+static char video3[3] = {
+ 0xBE, 0x00, 0x79,
+};
+static char video4[53] = {
+ 0xD1, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char video5[53] = {
+ 0xD2, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char video6[53] = {
+ 0xD3, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char video7[53] = {
+ 0xD4, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char video8[53] = {
+ 0xD5, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char video9[53] = {
+ 0xD6, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x32, 0x00,
+ 0x4F, 0x00, 0x65, 0x00,
+ 0x8B, 0x00, 0xA8, 0x00,
+ 0xD5, 0x00, 0xF7, 0x01,
+ 0x2B, 0x01, 0x54, 0x01,
+ 0x8E, 0x01, 0xBB, 0x01,
+ 0xBC, 0x01, 0xE3, 0x02,
+ 0x08, 0x02, 0x1C, 0x02,
+ 0x39, 0x02, 0x4F, 0x02,
+ 0x76, 0x02, 0xA3, 0x02,
+ 0xE3, 0x03, 0x12, 0x03,
+ 0x4C, 0x03, 0x66, 0x03,
+ 0x9A,
+};
+static char video10[4] = {
+ 0xB0, 0x0A, 0x0A, 0x0A,
+};
+static char video11[4] = {
+ 0xB1, 0x0A, 0x0A, 0x0A,
+};
+static char video12[4] = {
+ 0xBA, 0x24, 0x24, 0x24,
+};
+static char video13[4] = {
+ 0xB9, 0x24, 0x24, 0x24,
+};
+static char video14[4] = {
+ 0xB8, 0x24, 0x24, 0x24,
+};
+static char video15[6] = {
+ 0xF0, 0x55, 0xAA, 0x52,
+ 0x08, 0x00,
+};
+static char video16[2] = {
+ 0xB3, 0x00,
+};
+static char video17[2] = {
+ 0xB4, 0x10,
+};
+static char video18[2] = {
+ 0xB6, 0x02,
+};
+static char video19[3] = {
+ 0xB1, 0xFC, 0x06,
+};
+static char video20[4] = {
+ 0xBC, 0x05, 0x05, 0x05,
+};
+static char video21[3] = {
+ 0xB7, 0x20, 0x20,
+};
+static char video22[5] = {
+ 0xB8, 0x01, 0x03, 0x03,
+ 0x03,
+};
+static char video23[19] = {
+ 0xC8, 0x01, 0x00, 0x78,
+ 0x50, 0x78, 0x50, 0x78,
+ 0x50, 0x78, 0x50, 0xC8,
+ 0x3C, 0x3C, 0xC8, 0xC8,
+ 0x3C, 0x3C, 0xC8,
+};
+static char video24[6] = {
+ 0xBD, 0x01, 0x84, 0x07,
+ 0x31, 0x00,
+};
+static char video25[6] = {
+ 0xBE, 0x01, 0x84, 0x07,
+ 0x31, 0x00,
+};
+static char video26[6] = {
+ 0xBF, 0x01, 0x84, 0x07,
+ 0x31, 0x00,
+};
+static char video27[2] = {
+ 0x35, 0x00,
+};
+static struct dsi_cmd_desc nt35510_video_display_on_cmds[] = {
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video0), video0},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video1), video1},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video2), video2},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video3), video3},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video4), video4},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video5), video5},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video6), video6},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video7), video7},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video8), video8},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video9), video9},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video10), video10},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video11), video11},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video12), video12},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video13), video13},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video14), video14},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video15), video15},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video16), video16},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video17), video17},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video18), video18},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video19), video19},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video20), video20},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video21), video21},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video22), video22},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video23), video23},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video24), video24},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video25), video25},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video26), video26},
+ {DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video27), video27},
+ {DTYPE_DCS_WRITE, 1, 0, 0, NT35510_SLEEP_OFF_DELAY, sizeof(exit_sleep),
+ exit_sleep},
+ {DTYPE_DCS_WRITE, 1, 0, 0, NT35510_DISPLAY_ON_DELAY, sizeof(display_on),
+ display_on},
+};
+
+static int mipi_nt35510_lcd_on(struct platform_device *pdev)
+{
+ struct msm_fb_data_type *mfd;
+ struct mipi_panel_info *mipi;
+
+ mfd = platform_get_drvdata(pdev);
+ if (!mfd)
+ return -ENODEV;
+
+ if (mfd->key != MFD_KEY)
+ return -EINVAL;
+
+ mipi = &mfd->panel_info.mipi;
+
+ if (mipi->mode == DSI_VIDEO_MODE) {
+ mipi_dsi_cmds_tx(mfd, &nt35510_tx_buf,
+ nt35510_video_display_on_cmds,
+ ARRAY_SIZE(nt35510_video_display_on_cmds));
+ } else if (mipi->mode == DSI_CMD_MODE) {
+ mipi_dsi_cmds_tx(mfd, &nt35510_tx_buf,
+ nt35510_cmd_display_on_cmds,
+ ARRAY_SIZE(nt35510_cmd_display_on_cmds));
+ }
+
+ return 0;
+}
+
+static int mipi_nt35510_lcd_off(struct platform_device *pdev)
+{
+ struct msm_fb_data_type *mfd;
+
+ pr_debug("mipi_nt35510_lcd_off E\n");
+
+ mfd = platform_get_drvdata(pdev);
+
+ if (!mfd)
+ return -ENODEV;
+ if (mfd->key != MFD_KEY)
+ return -EINVAL;
+
+ mipi_dsi_cmds_tx(mfd, &nt35510_tx_buf, nt35510_display_off_cmds,
+ ARRAY_SIZE(nt35510_display_off_cmds));
+
+ pr_debug("mipi_nt35510_lcd_off X\n");
+ return 0;
+}
+
+static int __devinit mipi_nt35510_lcd_probe(struct platform_device *pdev)
+{
+ pr_debug("%s\n", __func__);
+
+ if (pdev->id == 0) {
+ mipi_nt35510_pdata = pdev->dev.platform_data;
+ return 0;
+ }
+
+ msm_fb_add_device(pdev);
+
+ return 0;
+}
+
+static struct platform_driver this_driver = {
+ .probe = mipi_nt35510_lcd_probe,
+ .driver = {
+ .name = "mipi_NT35510",
+ },
+};
+
+static void mipi_nt35510_set_backlight(struct msm_fb_data_type *mfd)
+{
+ /* Add backlight changes later*/
+ return;
+}
+
+static struct msm_fb_panel_data nt35510_panel_data = {
+ .on = mipi_nt35510_lcd_on,
+ .off = mipi_nt35510_lcd_off,
+ .set_backlight = mipi_nt35510_set_backlight,
+};
+
+static int ch_used[3];
+
+static int mipi_nt35510_lcd_init(void)
+{
+ mipi_dsi_buf_alloc(&nt35510_tx_buf, DSI_BUF_SIZE);
+ mipi_dsi_buf_alloc(&nt35510_rx_buf, DSI_BUF_SIZE);
+
+ return platform_driver_register(&this_driver);
+}
+int mipi_nt35510_device_register(struct msm_panel_info *pinfo,
+ u32 channel, u32 panel)
+{
+ struct platform_device *pdev = NULL;
+ int ret;
+
+ if ((channel >= 3) || ch_used[channel])
+ return -ENODEV;
+
+ ch_used[channel] = TRUE;
+
+ ret = mipi_nt35510_lcd_init();
+ if (ret) {
+ pr_err("mipi_nt35510_lcd_init() failed with ret %u\n", ret);
+ return ret;
+ }
+
+ pdev = platform_device_alloc("mipi_NT35510", (panel << 8)|channel);
+ if (!pdev)
+ return -ENOMEM;
+
+ nt35510_panel_data.panel_info = *pinfo;
+
+ ret = platform_device_add_data(pdev, &nt35510_panel_data,
+ sizeof(nt35510_panel_data));
+ if (ret) {
+ pr_debug("%s: platform_device_add_data failed!\n", __func__);
+ goto err_device_put;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ pr_debug("%s: platform_device_register failed!\n", __func__);
+ goto err_device_put;
+ }
+
+ return 0;
+
+err_device_put:
+ platform_device_put(pdev);
+ return ret;
+}
diff --git a/drivers/video/msm/mipi_NT35510.h b/drivers/video/msm/mipi_NT35510.h
new file mode 100644
index 0000000..5c81875
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35510.h
@@ -0,0 +1,20 @@
+/* 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.
+ *
+ */
+
+#ifndef MIPI_NT35510_H
+#define MIPI_NT35510_H
+
+int mipi_nt35510_device_register(struct msm_panel_info *pinfo,
+ u32 channel, u32 panel);
+
+#endif /* MIPI_NT35510_H */
diff --git a/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c b/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c
new file mode 100644
index 0000000..2c4ee3e
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c
@@ -0,0 +1,98 @@
+/* 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 "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_NT35510.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_cmd_mode_phy_db = {
+ /* DSI Bit Clock at 500 MHz, 2 lane, RGB888 */
+ /* regulator */
+ {0x03, 0x01, 0x01, 0x00},
+ /* timing */
+ {0xb9, 0x8e, 0x1f, 0x00, 0x98, 0x9c, 0x22, 0x90,
+ 0x18, 0x03, 0x04},
+ /* phy ctrl */
+ {0x7f, 0x00, 0x00, 0x00},
+ /* strength */
+ {0xbb, 0x02, 0x06, 0x00},
+ /* pll control */
+ {0x01, 0xec, 0x31, 0xd2, 0x00, 0x40, 0x37, 0x62,
+ 0x01, 0x0f, 0x07,
+ 0x05, 0x14, 0x03, 0x0, 0x0, 0x0, 0x20, 0x0, 0x02, 0x0},
+};
+
+static int mipi_cmd_nt35510_wvga_pt_init(void)
+{
+ int ret;
+
+ if (msm_fb_detect_client("mipi_cmd_nt35510_wvga"))
+ return 0;
+
+ pinfo.xres = 480;
+ pinfo.yres = 800;
+ pinfo.type = MIPI_CMD_PANEL;
+ pinfo.pdest = DISPLAY_1;
+ pinfo.wait_cycle = 0;
+ pinfo.bpp = 24;
+ pinfo.lcdc.h_back_porch = 100;
+ pinfo.lcdc.h_front_porch = 100;
+ pinfo.lcdc.h_pulse_width = 8;
+ pinfo.lcdc.v_back_porch = 20;
+ pinfo.lcdc.v_front_porch = 20;
+ pinfo.lcdc.v_pulse_width = 1;
+
+ pinfo.lcdc.border_clr = 0; /* blk */
+ pinfo.lcdc.underflow_clr = 0xff; /* blue */
+ pinfo.lcdc.hsync_skew = 0;
+ pinfo.bl_max = 100;
+ pinfo.bl_min = 1;
+ pinfo.fb_num = 2;
+
+ pinfo.clk_rate = 499000000;
+
+ pinfo.lcd.vsync_enable = TRUE;
+ pinfo.lcd.hw_vsync_mode = TRUE;
+ pinfo.lcd.refx100 = 6000; /* adjust refx100 to prevent tearing */
+
+ pinfo.mipi.mode = DSI_CMD_MODE;
+ pinfo.mipi.dst_format = DSI_CMD_DST_FORMAT_RGB888;
+ pinfo.mipi.vc = 0;
+ pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+ pinfo.mipi.data_lane0 = TRUE;
+ pinfo.mipi.data_lane1 = TRUE;
+ pinfo.mipi.t_clk_post = 0x20;
+ pinfo.mipi.t_clk_pre = 0x2F;
+ pinfo.mipi.stream = 0; /* dma_p */
+ pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+ pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+ pinfo.mipi.te_sel = 1; /* TE from vsync gpio */
+ pinfo.mipi.interleave_max = 1;
+ pinfo.mipi.insert_dcs_cmd = TRUE;
+ pinfo.mipi.wr_mem_continue = 0x3c;
+ pinfo.mipi.wr_mem_start = 0x2c;
+ pinfo.mipi.dsi_phy_db = &dsi_cmd_mode_phy_db;
+ pinfo.mipi.tx_eot_append = 0x01;
+ pinfo.mipi.rx_eot_ignore = 0x0;
+ pinfo.mipi.dlane_swap = 0x01;
+
+ ret = mipi_nt35510_device_register(&pinfo, MIPI_DSI_PRIM,
+ MIPI_DSI_PANEL_WVGA_PT);
+ if (ret)
+ pr_err("%s: failed to register device!\n", __func__);
+
+ return ret;
+}
+
+module_init(mipi_cmd_nt35510_wvga_pt_init);
diff --git a/drivers/video/msm/mipi_NT35510_video_wvga_pt.c b/drivers/video/msm/mipi_NT35510_video_wvga_pt.c
new file mode 100644
index 0000000..82e03b2
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35510_video_wvga_pt.c
@@ -0,0 +1,108 @@
+/* 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 "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_NT35510.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+ /* DSI Bit Clock at 500 MHz, 2 lane, RGB888 */
+ /* regulator */
+ {0x03, 0x01, 0x01, 0x00},
+ /* timing */
+ {0xb9, 0x8e, 0x1f, 0x00, 0x98, 0x9c, 0x22, 0x90,
+ 0x18, 0x03, 0x04},
+ /* phy ctrl */
+ {0x7f, 0x00, 0x00, 0x00},
+ /* strength */
+ {0xbb, 0x02, 0x06, 0x00},
+ /* pll control */
+ {0x00, 0xec, 0x31, 0xd2, 0x00, 0x40, 0x37, 0x62,
+ 0x01, 0x0f, 0x07,
+ 0x05, 0x14, 0x03, 0x0, 0x0, 0x0, 0x20, 0x0, 0x02, 0x0},
+};
+
+static int mipi_video_nt35510_wvga_pt_init(void)
+{
+ int ret;
+
+ if (msm_fb_detect_client("mipi_video_nt35510_wvga"))
+ return 0;
+
+ pinfo.xres = 480;
+ pinfo.yres = 800;
+ pinfo.type = MIPI_VIDEO_PANEL;
+ pinfo.pdest = DISPLAY_1;
+ pinfo.wait_cycle = 0;
+ pinfo.bpp = 24;
+ pinfo.lcdc.h_back_porch = 100;
+ pinfo.lcdc.h_front_porch = 100;
+ pinfo.lcdc.h_pulse_width = 8;
+ pinfo.lcdc.v_back_porch = 20;
+ pinfo.lcdc.v_front_porch = 20;
+ pinfo.lcdc.v_pulse_width = 1;
+ pinfo.lcdc.border_clr = 0; /* blk */
+ pinfo.lcdc.underflow_clr = 0xff; /* blue */
+ /* number of dot_clk cycles HSYNC active edge is
+ delayed from VSYNC active edge */
+ pinfo.lcdc.hsync_skew = 0;
+ pinfo.clk_rate = 499000000;
+ pinfo.bl_max = 100; /*16; CHECK THIS!!!*/
+ pinfo.bl_min = 1;
+ pinfo.fb_num = 2;
+
+ pinfo.mipi.mode = DSI_VIDEO_MODE;
+ /* send HSA and HE following VS/VE packet */
+ pinfo.mipi.pulse_mode_hsa_he = TRUE;
+ pinfo.mipi.hfp_power_stop = TRUE; /* LP-11 during the HFP period */
+ pinfo.mipi.hbp_power_stop = TRUE; /* LP-11 during the HBP period */
+ pinfo.mipi.hsa_power_stop = TRUE; /* LP-11 during the HSA period */
+ /* LP-11 or let Command Mode Engine send packets in
+ HS or LP mode for the BLLP of the last line of a frame */
+ pinfo.mipi.eof_bllp_power_stop = TRUE;
+ /* LP-11 or let Command Mode Engine send packets in
+ HS or LP mode for packets sent during BLLP period */
+ pinfo.mipi.bllp_power_stop = TRUE;
+
+ pinfo.mipi.traffic_mode = DSI_BURST_MODE;
+ pinfo.mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+ pinfo.mipi.vc = 0;
+ pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB; /* RGB */
+ pinfo.mipi.data_lane0 = TRUE;
+ pinfo.mipi.data_lane1 = TRUE;
+
+ pinfo.mipi.t_clk_post = 0x20;
+ pinfo.mipi.t_clk_pre = 0x2f;
+
+ pinfo.mipi.stream = 0; /* dma_p */
+ pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+ pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+ pinfo.mipi.frame_rate = 60; /* FIXME */
+
+ pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+ pinfo.mipi.dlane_swap = 0x01;
+ /* append EOT at the end of data burst */
+ pinfo.mipi.tx_eot_append = 0x01;
+
+ ret = mipi_nt35510_device_register(&pinfo, MIPI_DSI_PRIM,
+ MIPI_DSI_PANEL_WVGA_PT);
+
+ if (ret)
+ pr_err("%s: failed to register device!\n", __func__);
+
+ return ret;
+}
+
+module_init(mipi_video_nt35510_wvga_pt_init);
diff --git a/drivers/video/msm/mipi_chimei_wuxga.c b/drivers/video/msm/mipi_chimei_wuxga.c
new file mode 100644
index 0000000..c63df46
--- /dev/null
+++ b/drivers/video/msm/mipi_chimei_wuxga.c
@@ -0,0 +1,196 @@
+/* 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.
+ *
+ */
+
+/*
+ * Chimei WUXGA LVDS Panel driver.
+ * The panel model is N101JSF-L21.
+ *
+ * The panel interface includes:
+ * 1. LVDS input for video (clock & data).
+ * 2. few configuration pins to control 3D module: Enable, Mode (2D/3D).
+ * 3. Backlight LED control (PWM 200 HZ).
+ *
+ * This panel is controled via the Toshiba DSI-to-LVDS bridge.
+ *
+ */
+
+/* #define DEBUG 1 */
+
+#include "msm_fb.h"
+#include "msm_fb_panel.h"
+#include "mipi_dsi.h"
+#include "mipi_tc358764_dsi2lvds.h"
+
+#define MHZ (1000*1000)
+
+/**
+ * Panel info parameters.
+ * The panel info is passed to the mipi framebuffer driver.
+ */
+static struct msm_panel_info chimei_wuxga_pinfo;
+
+/**
+ * The mipi_dsi_phy_ctrl is calculated according to the
+ * "dsi_timing_program.xlsm" excel sheet.
+ * Output is based on: 1200x1920, RGB565, 4 lanes , 58 frames
+ * per second.
+ */
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+ /* DSIPHY_REGULATOR_CTRL */
+ .regulator = {0x03, 0x0a, 0x04, 0x00, 0x20}, /* common 8960 */
+ /* DSIPHY_CTRL */
+ .ctrl = {0x5f, 0x00, 0x00, 0x10}, /* common 8960 */
+ /* DSIPHY_STRENGTH_CTRL */
+ .strength = {0xff, 0x00, 0x06, 0x00}, /* common 8960 */
+ /* DSIPHY_TIMING_CTRL */
+ .timing = { 0xC9, 0x92, 0x29, /* panel specific */
+ 0, /* DSIPHY_TIMING_CTRL_3 = 0 */
+ 0x2E, 0x9B, 0x2C, 0x94, 0x2E, 0x03, 0x04}, /* panel specific */
+
+ /* DSIPHY_PLL_CTRL */
+ .pll = { 0x00, /* common 8960 */
+ /* VCO */
+ 0x32, (0x01 | 0x30) , (0x19 | 0xC0), /* panel specific */
+ 0x00, 0x50, 0x48, 0x63,
+ 0x77, 0x88, 0x99, /* Auto update by dsi-mipi driver */
+ 0x00, 0x14, 0x03, 0x00, 0x02, /* common 8960 */
+ 0x00, 0x20, 0x00, 0x01 }, /* common 8960 */
+};
+
+/**
+ * Module init.
+ *
+ * Register the panel-info.
+ *
+ * Some parameters are from the panel datasheet
+ * and other are *calculated* by the "dsi_timing_program.xlsm"
+ * excel file
+ *
+ * @return int
+ */
+static int __init mipi_chimei_wuxga_init(void)
+{
+ int ret;
+ struct msm_panel_info *pinfo = &chimei_wuxga_pinfo;
+
+ if (msm_fb_detect_client("mipi_video_chimei_wuxga"))
+ return 0;
+
+ pr_info("mipi-dsi chimei wuxga (1200x1920) driver ver 1.0.\n");
+
+ /* Portrait */
+ pinfo->xres = 1200;
+ pinfo->yres = 1920;
+ pinfo->type = MIPI_VIDEO_PANEL;
+ pinfo->pdest = DISPLAY_1; /* Primary Display */
+ pinfo->wait_cycle = 0;
+ pinfo->bpp = 24; /* RGB565 requires 24 bits-per-pixel :-O */
+ pinfo->fb_num = 2; /* using two frame buffers */
+
+ /*
+ * The CMI panel requires 80 MHZ LVDS-CLK.
+ * The D2L bridge drives the LVDS-CLK from the DSI-CLK.
+ * The DSI-CLK = bitclk/2, 640 MHZ/2= 320 MHZ.
+ * LVDS-CLK = DSI-CLK/4 , 320 MHZ/4= 80 MHZ.
+ */
+
+ pinfo->clk_rate = 640 * MHZ ; /* bitclk Calculated */
+
+ /*
+ * this panel is operated by DE,
+ * vsycn and hsync are ignored
+ */
+
+ pinfo->lcdc.h_front_porch = 16; /* thfp */
+ pinfo->lcdc.h_back_porch = 160; /* thb */
+ pinfo->lcdc.h_pulse_width = 32; /* thpw */
+
+ pinfo->lcdc.v_front_porch = 0; /* tvfp */
+ pinfo->lcdc.v_back_porch = 26; /* tvb */
+ pinfo->lcdc.v_pulse_width = 6; /* tvpw */
+
+ pinfo->lcdc.border_clr = 0; /* black */
+ pinfo->lcdc.underflow_clr = 0xff; /* blue */
+
+ pinfo->lcdc.hsync_skew = 0;
+
+ /* Backlight levels - controled via PMIC pwm gpio */
+ pinfo->bl_max = 15;
+ pinfo->bl_min = 1;
+
+ /* mipi - general */
+ pinfo->mipi.vc = 0; /* virtual channel */
+ pinfo->mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+ pinfo->mipi.tx_eot_append = true;
+ pinfo->mipi.t_clk_post = 34; /* Calculated */
+ pinfo->mipi.t_clk_pre = 69; /* Calculated */
+
+ pinfo->mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+
+ /* Four lanes are recomended for 1920x1200 at 60 frames per second */
+ pinfo->mipi.frame_rate = 45; /* 45 frames per second */
+ pinfo->mipi.data_lane0 = true;
+ pinfo->mipi.data_lane1 = true;
+ pinfo->mipi.data_lane2 = true;
+ pinfo->mipi.data_lane3 = true;
+
+ pinfo->mipi.mode = DSI_VIDEO_MODE;
+ /*
+ * Note: The CMI panel input is RGB888,
+ * thus the DSI-to-LVDS bridge output is RGB888.
+ * This parameter selects the DSI-Core output to the bridge.
+ */
+ pinfo->mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB565;
+
+ /* mipi - video mode */
+ pinfo->mipi.traffic_mode = DSI_NON_BURST_SYNCH_EVENT;
+ pinfo->mipi.pulse_mode_hsa_he = false; /* sync mode */
+
+ pinfo->mipi.hfp_power_stop = false;
+ pinfo->mipi.hbp_power_stop = false;
+ pinfo->mipi.hsa_power_stop = false;
+ pinfo->mipi.eof_bllp_power_stop = false;
+ pinfo->mipi.bllp_power_stop = false;
+
+ /* mipi - command mode */
+ pinfo->mipi.te_sel = 1; /* TE from vsycn gpio */
+ pinfo->mipi.interleave_max = 1;
+ /* The bridge supports only Generic Read/Write commands */
+ pinfo->mipi.insert_dcs_cmd = false;
+ pinfo->mipi.wr_mem_continue = 0;
+ pinfo->mipi.wr_mem_start = 0;
+ pinfo->mipi.stream = false; /* dma_p */
+ pinfo->mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+ pinfo->mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+ /*
+ * toshiba d2l chip does not need max_pkt_size dcs cmd
+ * client reply len is directly configure through
+ * RDPKTLN register (0x0404)
+ */
+ pinfo->mipi.no_max_pkt_size = 1;
+ pinfo->mipi.force_clk_lane_hs = 1;
+
+ pinfo->is_3d_panel = FB_TYPE_3D_PANEL;
+
+ ret = mipi_tc358764_dsi2lvds_register(pinfo, MIPI_DSI_PRIM, 1);
+ if (ret)
+ pr_err("%s: failed to register device!\n", __func__);
+
+ return ret;
+}
+
+module_init(mipi_chimei_wuxga_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Chimei WUXGA LVDS Panel driver");
+MODULE_AUTHOR("Amir Samuelov <amirs@codeaurora.org>");
diff --git a/drivers/video/msm/mipi_novatek.c b/drivers/video/msm/mipi_novatek.c
index caa4114..ed0dee4 100644
--- a/drivers/video/msm/mipi_novatek.c
+++ b/drivers/video/msm/mipi_novatek.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, 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
@@ -461,6 +461,7 @@
struct mipi_panel_info *mipi;
struct platform_device *current_pdev;
static struct mipi_dsi_phy_ctrl *phy_settings;
+ static char dlane_swap;
if (pdev->id == 0) {
mipi_novatek_pdata = pdev->dev.platform_data;
@@ -471,6 +472,11 @@
}
if (mipi_novatek_pdata
+ && mipi_novatek_pdata->dlane_swap) {
+ dlane_swap = (mipi_novatek_pdata->dlane_swap);
+ }
+
+ if (mipi_novatek_pdata
&& mipi_novatek_pdata->fpga_3d_config_addr)
mipi_novatek_3d_init(mipi_novatek_pdata
->fpga_3d_config_addr, mipi_novatek_pdata->fpga_ctrl_mode);
@@ -499,6 +505,9 @@
if (phy_settings != NULL)
mipi->dsi_phy_db = phy_settings;
+
+ if (dlane_swap)
+ mipi->dlane_swap = dlane_swap;
}
return 0;
}
diff --git a/drivers/video/msm/mipi_tc358764_dsi2lvds.c b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
index 8055bd0..fcb5163 100644
--- a/drivers/video/msm/mipi_tc358764_dsi2lvds.c
+++ b/drivers/video/msm/mipi_tc358764_dsi2lvds.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
@@ -68,7 +68,9 @@
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/pwm.h>
+#include <linux/gpio.h>
#include "msm_fb.h"
+#include "mdp4.h"
#include "mipi_dsi.h"
#include "mipi_tc358764_dsi2lvds.h"
@@ -186,7 +188,11 @@
#define DEBUG01 0x05A4 /* LVDS Data */
/* PWM */
-#define PWM_FREQ_HZ (66*1000) /* 66 KHZ */
+static u32 d2l_pwm_freq_hz = (66*1000);
+
+/* 1366x768 uses pwm at 66 KHZ */
+/* 1200x1920 uses pwm at 25 KHZ */
+#define PWM_FREQ_HZ (d2l_pwm_freq_hz)
#define PWM_LEVEL 15
#define PWM_PERIOD_USEC (USEC_PER_SEC / PWM_FREQ_HZ)
#define PWM_DUTY_LEVEL (PWM_PERIOD_USEC / PWM_LEVEL)
@@ -213,10 +219,17 @@
static struct dsi_buf d2l_rx_buf;
static int led_pwm;
static struct pwm_device *bl_pwm;
+static struct pwm_device *tn_pwm;
static int bl_level;
static u32 d2l_gpio_out_mask;
static u32 d2l_gpio_out_val;
+static u32 d2l_3d_gpio_enable;
+static u32 d2l_3d_gpio_mode;
+static int d2l_enable_3d;
+
static int mipi_d2l_init(void);
+static int mipi_d2l_enable_3d(struct msm_fb_data_type *mfd,
+ bool enable, bool mode);
/**
* Read a bridge register
@@ -236,7 +249,7 @@
mipi_dsi_buf_init(&d2l_tx_buf);
mipi_dsi_buf_init(&d2l_rx_buf);
- /* mutex had been acquried at dsi_on */
+ /* mutex had been acquired at mipi_dsi_on */
len = mipi_dsi_cmds_rx(mfd, &d2l_tx_buf, &d2l_rx_buf,
&cmd_read_reg, len);
@@ -247,7 +260,6 @@
pr_debug("%s: reg=0x%x.data=0x%08x.\n", __func__, reg, data);
-
return data;
}
@@ -256,9 +268,9 @@
*
* @param mfd
*
- * @return register data value
+ * @return int
*/
-static u32 mipi_d2l_write_reg(struct msm_fb_data_type *mfd, u16 reg, u32 data)
+static int mipi_d2l_write_reg(struct msm_fb_data_type *mfd, u16 reg, u32 data)
{
struct wr_cmd_payload payload;
struct dsi_cmd_desc cmd_write_reg = {
@@ -268,35 +280,25 @@
payload.addr = reg;
payload.data = data;
- /* mutex had been acquried at dsi_on */
+ /* mutex had been acquired at mipi_dsi_on */
mipi_dsi_cmds_tx(mfd, &d2l_tx_buf, &cmd_write_reg, 1);
pr_debug("%s: reg=0x%x. data=0x%x.\n", __func__, reg, data);
- return data;
+ return 0;
}
-/*
+static void mipi_d2l_read_status(struct msm_fb_data_type *mfd)
+{
+ mipi_d2l_read_reg(mfd, DSI_LANESTATUS0); /* 0x214 */
+ mipi_d2l_read_reg(mfd, DSI_LANESTATUS1); /* 0x218 */
+ mipi_d2l_read_reg(mfd, DSI_INTSTATUS); /* 0x220 */
+ mipi_d2l_read_reg(mfd, SYSSTAT); /* 0x500 */
+}
+
+/**
* Init the D2L bridge via the DSI interface for Video.
*
- * Register Addr Value
- * ===================================================
- * PPI_TX_RX_TA 0x013C 0x00040004
- * PPI_LPTXTIMECNT 0x0114 0x00000004
- * PPI_D0S_CLRSIPOCOUNT 0x0164 0x00000003
- * PPI_D1S_CLRSIPOCOUNT 0x0168 0x00000003
- * PPI_D2S_CLRSIPOCOUNT 0x016C 0x00000003
- * PPI_D3S_CLRSIPOCOUNT 0x0170 0x00000003
- * PPI_LANEENABLE 0x0134 0x0000001F
- * DSI_LANEENABLE 0x0210 0x0000001F
- * PPI_STARTPPI 0x0104 0x00000001
- * DSI_STARTDSI 0x0204 0x00000001
- * VPCTRL 0x0450 0x01000120
- * HTIM1 0x0454 0x002C0028
- * VTIM1 0x045C 0x001E0008
- * VFUEN 0x0464 0x00000001
- * LVCFG 0x049C 0x00000001
- *
* VPCTRL.EVTMODE (0x20) configuration bit is needed to determine whether
* video timing information is delivered in pulse mode or event mode.
* In pulse mode, both Sync Start and End packets are required.
@@ -304,15 +306,22 @@
*
* @param mfd
*
- * @return register data value
+ * @return int
*/
static int mipi_d2l_dsi_init_sequence(struct msm_fb_data_type *mfd)
{
struct mipi_panel_info *mipi = &mfd->panel_info.mipi;
u32 lanes_enable;
u32 vpctrl;
- u32 htime1 = 0x002C0028;
- u32 vtime1 = 0x001E0008;
+ u32 htime1;
+ u32 vtime1;
+ u32 ppi_tx_rx_ta; /* BTA Bus-Turn-Around */
+ u32 lvcfg;
+ u32 hbpr; /* Horizontal Back Porch */
+ u32 hpw; /* Horizontal Pulse Width */
+ u32 vbpr; /* Vertical Back Porch */
+ u32 vpw; /* Vertical Pulse Width */
+ bool vesa_rgb888 = false;
lanes_enable = 0x01; /* clock-lane enable */
lanes_enable |= (mipi->data_lane0 << 1);
@@ -330,25 +339,57 @@
return -EINVAL;
}
+ if (mfd->panel_info.clk_rate > 800*1000*1000) {
+ pr_err("%s.unsupported clk_rate %d.\n",
+ __func__, mfd->panel_info.clk_rate);
+ return -EINVAL;
+ }
+
+ pr_debug("%s.xres=%d.yres=%d.\n",
+ __func__, mfd->panel_info.xres, mfd->panel_info.yres);
+
+ hbpr = mfd->panel_info.lcdc.h_back_porch;
+ hpw = mfd->panel_info.lcdc.h_pulse_width;
+ vbpr = mfd->panel_info.lcdc.v_back_porch;
+ vpw = mfd->panel_info.lcdc.v_pulse_width;
+
+ htime1 = (hbpr << 16) + hpw;
+ vtime1 = (vbpr << 16) + vpw;
+ lvcfg = 0x0003; /* PCLK=DCLK/3, Dual Link, LVEN */
+ vpctrl = 0x01000120; /* Output RGB888 , Event-Mode , */
+ ppi_tx_rx_ta = 0x00040004;
+
+ if (mfd->panel_info.xres == 1366) {
+ ppi_tx_rx_ta = 0x00040004;
+ lvcfg = 0x01; /* LVEN */
+ vesa_rgb888 = true;
+ }
+
+ if (mfd->panel_info.xres == 1200) {
+ lvcfg = 0x0103; /* PCLK=DCLK/4, Dual Link, LVEN */
+ vesa_rgb888 = true;
+ }
+
pr_debug("%s.htime1=0x%x.\n", __func__, htime1);
pr_debug("%s.vtime1=0x%x.\n", __func__, vtime1);
pr_debug("%s.vpctrl=0x%x.\n", __func__, vpctrl);
- pr_debug("%s.lanes_enable=0x%x.\n", __func__, lanes_enable);
-
+ pr_debug("%s.lvcfg=0x%x.\n", __func__, lvcfg);
mipi_d2l_write_reg(mfd, SYSRST, 0xFF);
msleep(30);
- /* VESA format instead of JEIDA format for RGB888 */
- mipi_d2l_write_reg(mfd, LVMX0003, 0x03020100);
- mipi_d2l_write_reg(mfd, LVMX0407, 0x08050704);
- mipi_d2l_write_reg(mfd, LVMX0811, 0x0F0E0A09);
- mipi_d2l_write_reg(mfd, LVMX1215, 0x100D0C0B);
- mipi_d2l_write_reg(mfd, LVMX1619, 0x12111716);
- mipi_d2l_write_reg(mfd, LVMX2023, 0x1B151413);
- mipi_d2l_write_reg(mfd, LVMX2427, 0x061A1918);
+ if (vesa_rgb888) {
+ /* VESA format instead of JEIDA format for RGB888 */
+ mipi_d2l_write_reg(mfd, LVMX0003, 0x03020100);
+ mipi_d2l_write_reg(mfd, LVMX0407, 0x08050704);
+ mipi_d2l_write_reg(mfd, LVMX0811, 0x0F0E0A09);
+ mipi_d2l_write_reg(mfd, LVMX1215, 0x100D0C0B);
+ mipi_d2l_write_reg(mfd, LVMX1619, 0x12111716);
+ mipi_d2l_write_reg(mfd, LVMX2023, 0x1B151413);
+ mipi_d2l_write_reg(mfd, LVMX2427, 0x061A1918);
+ }
- mipi_d2l_write_reg(mfd, PPI_TX_RX_TA, 0x00040004); /* BTA */
+ mipi_d2l_write_reg(mfd, PPI_TX_RX_TA, ppi_tx_rx_ta); /* BTA */
mipi_d2l_write_reg(mfd, PPI_LPTXTIMECNT, 0x00000004);
mipi_d2l_write_reg(mfd, PPI_D0S_CLRSIPOCOUNT, 0x00000003);
mipi_d2l_write_reg(mfd, PPI_D1S_CLRSIPOCOUNT, 0x00000003);
@@ -363,7 +404,7 @@
mipi_d2l_write_reg(mfd, HTIM1, htime1);
mipi_d2l_write_reg(mfd, VTIM1, vtime1);
mipi_d2l_write_reg(mfd, VFUEN, 0x00000001);
- mipi_d2l_write_reg(mfd, LVCFG, 0x00000001); /* Enables LVDS tx */
+ mipi_d2l_write_reg(mfd, LVCFG, lvcfg); /* Enables LVDS tx */
return 0;
}
@@ -400,6 +441,35 @@
return ret;
}
+ return 0;
+}
+
+/**
+ * Set TN CLK.
+ *
+ * @param pwm
+ * @param level
+ *
+ * @return int
+ */
+static int mipi_d2l_set_tn_clk(struct pwm_device *pwm, u32 usec)
+{
+ int ret = 0;
+
+ pr_debug("%s: usec=%d.\n", __func__, usec);
+
+ ret = pwm_config(pwm, usec/2 , usec);
+ if (ret) {
+ pr_err("%s: pwm_config() failed err=%d.\n", __func__, ret);
+ return ret;
+ }
+
+ ret = pwm_enable(pwm);
+ if (ret) {
+ pr_err("%s: pwm_enable() failed err=%d\n",
+ __func__, ret);
+ return ret;
+ }
return 0;
}
@@ -446,9 +516,14 @@
return ret;
mipi_d2l_write_reg(mfd, GPIOC, d2l_gpio_out_mask);
- /* Set GPIOs: gpio#4=U/D=0 , gpio#3=L/R=1 , gpio#2,1=CABC=0. */
+ /* Set gpio#4=U/D=0, gpio#3=L/R=1 , gpio#2,1=CABC=0, gpio#0=NA. */
mipi_d2l_write_reg(mfd, GPIOO, d2l_gpio_out_val);
+ if (mfd->panel_info.xres == 1366)
+ d2l_pwm_freq_hz = (66*1000);
+ else
+ d2l_pwm_freq_hz = (25*1000);
+
if (bl_level == 0)
bl_level = PWM_LEVEL * 2 / 3 ; /* Default ON value */
@@ -460,6 +535,10 @@
__func__, ret);
}
+ mipi_d2l_read_status(mfd);
+
+ mipi_d2l_enable_3d(mfd, false, false);
+
pr_info("%s.ret=%d.\n", __func__, ret);
return ret;
@@ -510,6 +589,98 @@
.set_backlight = mipi_d2l_set_backlight,
};
+static int mipi_d2l_enable_3d(struct msm_fb_data_type *mfd,
+ bool enable, bool mode)
+{
+ u32 tn_usec = 1000000 / 66; /* 66 HZ */
+
+ pr_debug("%s.enable=%d.mode=%d.\n", __func__, enable, mode);
+
+ gpio_direction_output(d2l_3d_gpio_enable, enable);
+ gpio_direction_output(d2l_3d_gpio_mode, mode);
+
+ mipi_d2l_set_tn_clk(tn_pwm, tn_usec);
+
+ return 0;
+}
+
+static ssize_t mipi_d2l_enable_3d_read(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return snprintf((char *)buf, sizeof(buf), "%u\n", d2l_enable_3d);
+}
+
+static ssize_t mipi_d2l_enable_3d_write(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ int ret = -1;
+ u32 data = 0;
+
+ if (sscanf((char *)buf, "%u", &data) != 1) {
+ dev_err(dev, "%s. Invalid input.\n", __func__);
+ ret = -EINVAL;
+ } else {
+ d2l_enable_3d = data;
+ if (data == 1) /* LANDSCAPE */
+ mipi_d2l_enable_3d(d2l_mfd, true, true);
+ else if (data == 2) /* PORTRAIT */
+ mipi_d2l_enable_3d(d2l_mfd, true, false);
+ else if (data == 0)
+ mipi_d2l_enable_3d(d2l_mfd, false, false);
+ else
+ pr_err("%s.Invalid value=%d.\n", __func__, data);
+ }
+
+ return count;
+}
+
+static struct device_attribute mipi_d2l_3d_barrier_attributes[] = {
+ __ATTR(enable_3d_barrier, 0666,
+ mipi_d2l_enable_3d_read,
+ mipi_d2l_enable_3d_write),
+};
+
+static int mipi_dsi_3d_barrier_sysfs_register(struct device *dev)
+{
+ int ret;
+
+ pr_debug("%s.d2l_3d_gpio_enable=%d.\n", __func__, d2l_3d_gpio_enable);
+ pr_debug("%s.d2l_3d_gpio_mode=%d.\n", __func__, d2l_3d_gpio_mode);
+
+ ret = device_create_file(dev, mipi_d2l_3d_barrier_attributes);
+ if (ret) {
+ pr_err("%s.failed to create 3D sysfs.\n", __func__);
+ goto err_device_create_file;
+ }
+
+ ret = gpio_request(d2l_3d_gpio_enable, "d2l_3d_gpio_enable");
+ if (ret) {
+ pr_err("%s.failed to get d2l_3d_gpio_enable=%d.\n",
+ __func__, d2l_3d_gpio_enable);
+ goto err_d2l_3d_gpio_enable;
+ }
+
+ ret = gpio_request(d2l_3d_gpio_mode, "d2l_3d_gpio_mode");
+ if (ret) {
+ pr_err("%s.failed to get d2l_3d_gpio_mode=%d.\n",
+ __func__, d2l_3d_gpio_mode);
+ goto err_d2l_3d_gpio_mode;
+ }
+
+ return 0;
+
+err_d2l_3d_gpio_mode:
+ gpio_free(d2l_3d_gpio_enable);
+err_d2l_3d_gpio_enable:
+ device_remove_file(dev, mipi_d2l_3d_barrier_attributes);
+err_device_create_file:
+
+ return ret;
+}
+
/**
* Probe for device.
*
@@ -530,7 +701,6 @@
pr_debug("%s.id=%d.\n", __func__, pdev->id);
if (pdev->id == 0) {
- /* d2l_common_pdata = platform_get_drvdata(pdev); */
d2l_common_pdata = pdev->dev.platform_data;
if (d2l_common_pdata == NULL) {
@@ -541,6 +711,8 @@
led_pwm = d2l_common_pdata->gpio_num[0];
d2l_gpio_out_mask = d2l_common_pdata->gpio_num[1] >> 8;
d2l_gpio_out_val = d2l_common_pdata->gpio_num[1] & 0xFF;
+ d2l_3d_gpio_enable = d2l_common_pdata->gpio_num[2];
+ d2l_3d_gpio_mode = d2l_common_pdata->gpio_num[3];
mipi_dsi_buf_alloc(&d2l_tx_buf, DSI_BUF_SIZE);
mipi_dsi_buf_alloc(&d2l_rx_buf, DSI_BUF_SIZE);
@@ -567,10 +739,20 @@
}
} else {
- pr_info("%s. led_pwm is invalid.\n", __func__);
+ pr_err("%s. led_pwm is invalid.\n", __func__);
}
- /* pinfo = platform_get_drvdata(pdev); */
+ tn_pwm = pwm_request(1, "3D_TN_clk");
+ if (tn_pwm == NULL || IS_ERR(tn_pwm)) {
+ pr_err("%s pwm_request() failed.id=%d.tn_pwm=%d.\n",
+ __func__, 1, (int) tn_pwm);
+ tn_pwm = NULL;
+ return -EIO;
+ } else {
+ pr_debug("%s.pwm_request() ok.pwm-id=%d.\n", __func__, 1);
+
+ }
+
pinfo = pdev->dev.platform_data;
if (pinfo == NULL) {
@@ -584,6 +766,9 @@
msm_fb_add_device(pdev);
+ if (pinfo->is_3d_panel)
+ mipi_dsi_3d_barrier_sysfs_register(&(pdev->dev));
+
return ret;
}
@@ -667,6 +852,7 @@
static int mipi_d2l_init(void)
{
pr_debug("%s.\n", __func__);
+
return platform_driver_register(&d2l_driver);
}
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 42fa2ba..489e6d2 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -1520,8 +1520,8 @@
pdata->set_backlight(mfd);
bl_level_old = unset_bl_level;
up(&mfd->sem);
+ bl_updated = 1;
}
- bl_updated = 1;
}
++mfd->panel_info.frame_count;
@@ -2624,8 +2624,8 @@
pdata->set_backlight(mfd);
bl_level_old = unset_bl_level;
up(&mfd->sem);
+ bl_updated = 1;
}
- bl_updated = 1;
}
return ret;
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/mfd/pm8xxx/pm8038.h b/include/linux/mfd/pm8xxx/pm8038.h
index 203095a..4d3c78f 100644
--- a/include/linux/mfd/pm8xxx/pm8038.h
+++ b/include/linux/mfd/pm8xxx/pm8038.h
@@ -30,6 +30,7 @@
#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
#include <linux/mfd/pm8xxx/pm8921-charger.h>
#include <linux/mfd/pm8xxx/pm8921-bms.h>
+#include <linux/leds-pm8xxx.h>
#include <linux/mfd/pm8xxx/ccadc.h>
#define PM8038_CORE_DEV_NAME "pm8038-core"
@@ -75,6 +76,7 @@
struct pm8921_charger_platform_data *charger_pdata;
struct pm8921_bms_platform_data *bms_pdata;
struct pm8xxx_adc_platform_data *adc_pdata;
+ struct pm8xxx_led_platform_data *leds_pdata;
struct pm8xxx_ccadc_platform_data *ccadc_pdata;
};
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 427465d..07d5af6 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -1,6 +1,7 @@
/* include/linux/msm_mdp.h
*
* Copyright (C) 2007 Google Incorporated
+ * 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
@@ -77,6 +78,7 @@
MDP_RGB_565, /* RGB 565 planer */
MDP_XRGB_8888, /* RGB 888 padded */
MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planer w/ Cb is in MSB */
+ MDP_Y_CBCR_H2V2_ADRENO,
MDP_ARGB_8888, /* ARGB 888 */
MDP_RGB_888, /* RGB 888 planer */
MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planer w/ Cr is in MSB */
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/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 2cbe6ce..037cfe7 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -164,6 +164,7 @@
* @enable_dcd: Enable Data Contact Detection circuit. if not set
* wait for 600msec before proceeding to primary
* detection.
+ * @bus_scale_table: parameters for bus bandwidth requirements
*/
struct msm_otg_platform_data {
int *phy_init_seq;
@@ -179,6 +180,7 @@
bool disable_reset_on_disconnect;
u32 swfi_latency;
bool enable_dcd;
+ struct msm_bus_scale_pdata *bus_scale_table;
};
/**
@@ -211,6 +213,7 @@
collapse when cable is connected.
* @id_timer: The timer used for polling ID line to detect ACA states.
* @xo_handle: TCXO buffer handle
+ * @bus_perf_client: Bus performance client handle to request BUS bandwidth
*/
struct msm_otg {
struct otg_transceiver otg;
@@ -241,6 +244,7 @@
struct timer_list id_timer;
unsigned long caps;
struct clk *xo_handle;
+ uint32_t bus_perf_client;
/*
* Allowing PHY power collpase turns off the HSUSB 3.3v and 1.8v
* analog regulators while going to low power mode.
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index c97c664..9759b32 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.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
@@ -42,6 +42,7 @@
enum wcnss_opcode opcode);
int req_riva_power_on_lock(char *driver_name);
int free_riva_power_on_lock(char *driver_name);
+unsigned int wcnss_get_serial_number(void);
#define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev)
#define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data))
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 7caafb6..5dd1445 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -58,6 +58,7 @@
#define MSG_ID_STATS_AWB_AEC 39
#define MSG_ID_OUTPUT_PRIMARY 40
#define MSG_ID_OUTPUT_SECONDARY 41
+#define MSG_ID_STATS_COMPOSITE 42
/* ISP command IDs */
#define VFE_CMD_DUMMY_0 0
diff --git a/kernel/printk.c b/kernel/printk.c
index dbaa948..3c31395 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -41,7 +41,7 @@
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <linux/rculist.h>
-
+#include <mach/msm_rtb.h>
#include <asm/uaccess.h>
/*
@@ -784,6 +784,11 @@
{
va_list args;
int r;
+#ifdef CONFIG_MSM_RTB
+ void *caller = __builtin_return_address(0);
+
+ uncached_logk_pc(LOGK_LOGBUF, caller, (void *)log_end);
+#endif
#ifdef CONFIG_KGDB_KDB
if (unlikely(kdb_trap_printk)) {
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index e56fe35..b3b122f 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -686,6 +686,14 @@
bdi_unregister(bdi);
+ /*
+ * If bdi_unregister() had already been called earlier, the
+ * wakeup_timer could still be armed because bdi_prune_sb()
+ * can race with the bdi_wakeup_thread_delayed() calls from
+ * __mark_inode_dirty().
+ */
+ del_timer_sync(&bdi->wb.wakeup_timer);
+
for (i = 0; i < NR_BDI_STAT_ITEMS; i++)
percpu_counter_destroy(&bdi->bdi_stat[i]);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index f0f2ac1..899c538 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -65,7 +65,7 @@
cp.peer_addr_type = conn->dst_type;
cp.conn_interval_min = cpu_to_le16(0x0008);
cp.conn_interval_max = cpu_to_le16(0x0100);
- cp.supervision_timeout = cpu_to_le16(0x0064);
+ cp.supervision_timeout = cpu_to_le16(1000);
cp.min_ce_len = cpu_to_le16(0x0001);
cp.max_ce_len = cpu_to_le16(0x0001);
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/msm7201.c b/sound/soc/msm/msm7201.c
index 9e041c7..6408cef 100644
--- a/sound/soc/msm/msm7201.c
+++ b/sound/soc/msm/msm7201.c
@@ -1,6 +1,6 @@
/* linux/sound/soc/msm/msm7201.c
*
- * Copyright (c) 2008-2009, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2011, 2012 Code Aurora Forum. All rights reserved.
*
* All source code in this file is licensed under the following license except
* where indicated.
@@ -40,6 +40,8 @@
#include <mach/msm_rpcrouter.h>
static struct msm_rpc_endpoint *snd_ep;
+static uint32_t snd_mute_ear_mute;
+static uint32_t snd_mute_mic_mute;
struct msm_snd_rpc_ids {
unsigned long prog;
@@ -99,7 +101,7 @@
* The number of devices supported is 26 (0 to 25)
*/
uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 25;
+ uinfo->value.integer.max = 36;
return 0;
}
@@ -107,6 +109,8 @@
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = (uint32_t)snd_rpc_ids.device;
+ ucontrol->value.integer.value[1] = snd_mute_ear_mute;
+ ucontrol->value.integer.value[2] = snd_mute_mic_mute;
return 0;
}
@@ -213,8 +217,11 @@
if (rc < 0) {
printk(KERN_ERR "%s: snd rpc call failed! rc = %d\n",
__func__, rc);
- } else
- printk(KERN_INFO "snd device connected \n");
+ } else {
+ printk(KERN_INFO "snd device connected\n");
+ snd_mute_ear_mute = ucontrol->value.integer.value[1];
+ snd_mute_mic_mute = ucontrol->value.integer.value[2];
+ }
return rc;
}
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",