diff options
Diffstat (limited to 'include')
31 files changed, 3500 insertions, 13 deletions
diff --git a/include/linux/cpu_pm.h b/include/linux/cpu_pm.h new file mode 100644 index 0000000..455b233 --- /dev/null +++ b/include/linux/cpu_pm.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2011 Google, Inc. + * + * Author: + * Colin Cross <ccross@android.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 _LINUX_CPU_PM_H +#define _LINUX_CPU_PM_H + +#include <linux/kernel.h> +#include <linux/notifier.h> + +/* + * When a CPU goes to a low power state that turns off power to the CPU's + * power domain, the contents of some blocks (floating point coprocessors, + * interrupt controllers, caches, timers) in the same power domain can + * be lost. The cpm_pm notifiers provide a method for platform idle, suspend, + * and hotplug implementations to notify the drivers for these blocks that + * they may be reset. + * + * All cpu_pm notifications must be called with interrupts disabled. + * + * The notifications are split into two classes: CPU notifications and CPU + * cluster notifications. + * + * CPU notifications apply to a single CPU and must be called on the affected + * CPU. They are used to save per-cpu context for affected blocks. + * + * CPU cluster notifications apply to all CPUs in a single power domain. They + * are used to save any global context for affected blocks, and must be called + * after all the CPUs in the power domain have been notified of the low power + * state. + */ + +/* + * Event codes passed as unsigned long val to notifier calls + */ +enum cpu_pm_event { + /* A single cpu is entering a low power state */ + CPU_PM_ENTER, + + /* A single cpu failed to enter a low power state */ + CPU_PM_ENTER_FAILED, + + /* A single cpu is exiting a low power state */ + CPU_PM_EXIT, + + /* A cpu power domain is entering a low power state */ + CPU_CLUSTER_PM_ENTER, + + /* A cpu power domain failed to enter a low power state */ + CPU_CLUSTER_PM_ENTER_FAILED, + + /* A cpu power domain is exiting a low power state */ + CPU_CLUSTER_PM_EXIT, +}; + +#ifdef CONFIG_CPU_PM +int cpu_pm_register_notifier(struct notifier_block *nb); +int cpu_pm_unregister_notifier(struct notifier_block *nb); +int cpu_pm_enter(void); +int cpu_pm_exit(void); +int cpu_cluster_pm_enter(void); +int cpu_cluster_pm_exit(void); + +#else + +static inline int cpu_pm_register_notifier(struct notifier_block *nb) +{ + return 0; +} + +static inline int cpu_pm_unregister_notifier(struct notifier_block *nb) +{ + return 0; +} + +static inline int cpu_pm_enter(void) +{ + return 0; +} + +static inline int cpu_pm_exit(void) +{ + return 0; +} + +static inline int cpu_cluster_pm_enter(void) +{ + return 0; +} + +static inline int cpu_cluster_pm_exit(void) +{ + return 0; +} +#endif +#endif diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index ae06dc9..905ea72 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -361,6 +361,9 @@ extern struct cpufreq_governor cpufreq_gov_conservative; #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE) extern struct cpufreq_governor cpufreq_gov_interactive; #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_interactive) +#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG) +extern struct cpufreq_governor cpufreq_gov_hotplug; +#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_hotplug) #endif @@ -402,5 +405,14 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, void cpufreq_frequency_table_put_attr(unsigned int cpu); +/* the following are for use in governors, or anywhere else */ +extern int cpufreq_frequency_table_next_lowest(struct cpufreq_policy *policy, + struct cpufreq_frequency_table *table, + int *index); + +extern int cpufreq_frequency_table_next_highest(struct cpufreq_policy *policy, + struct cpufreq_frequency_table *table, + int *index); + #endif /* _LINUX_CPUFREQ_H */ diff --git a/include/linux/fb.h b/include/linux/fb.h index f9d013d..e8cc747 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -226,6 +226,10 @@ struct fb_bitfield { #define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ #define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */ +#define FB_FLAG_RATIO_4_3 64 +#define FB_FLAG_RATIO_16_9 128 +#define FB_FLAG_PIXEL_REPEAT 256 + /* * Display rotation support */ @@ -439,6 +443,8 @@ struct file; #define FB_MISC_PRIM_COLOR 1 #define FB_MISC_1ST_DETAIL 2 /* First Detailed Timing is preferred */ +#define FB_MISC_HDMI 4 /* display supports HDMI signaling */ + struct fb_chroma { __u32 redx; /* in fraction of 1024 */ __u32 greenx; @@ -1104,6 +1110,7 @@ extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter); /* drivers/video/modedb.c */ #define VESA_MODEDB_SIZE 34 +#define CEA_MODEDB_SIZE 65 extern void fb_var_to_videomode(struct fb_videomode *mode, const struct fb_var_screeninfo *var); extern void fb_videomode_to_var(struct fb_var_screeninfo *var, @@ -1156,7 +1163,7 @@ struct fb_videomode { extern const char *fb_mode_option; extern const struct fb_videomode vesa_modes[]; -extern const struct fb_videomode cea_modes[64]; +extern const struct fb_videomode cea_modes[]; struct fb_modelist { struct list_head list; diff --git a/include/linux/hsi_char.h b/include/linux/hsi_char.h new file mode 100644 index 0000000..cfa6580 --- /dev/null +++ b/include/linux/hsi_char.h @@ -0,0 +1,71 @@ +/* + * hsi_char.h + * + * HSI character driver public declaration header file. + * + * Copyright (C) 2009 Nokia Corporation. All rights reserved. + * Copyright (C) 2009 Texas Instruments, Inc. + * + * Author: Andras Domokos <andras.domokos@nokia.com> + * Author: Sebastien JAN <s-jan@ti.com> + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef HSI_CHAR_H +#define HSI_CHAR_H + +#define HSI_CHAR_BASE 'S' +#define CS_IOW(num, dtype) _IOW(HSI_CHAR_BASE, num, dtype) +#define CS_IOR(num, dtype) _IOR(HSI_CHAR_BASE, num, dtype) +#define CS_IOWR(num, dtype) _IOWR(HSI_CHAR_BASE, num, dtype) +#define CS_IO(num) _IO(HSI_CHAR_BASE, num) + +#define CS_SEND_BREAK CS_IO(1) +#define CS_FLUSH_RX CS_IO(2) +#define CS_FLUSH_TX CS_IO(3) +#define CS_BOOTSTRAP CS_IO(4) +#define CS_SET_ACWAKELINE CS_IOW(5, unsigned int) +#define CS_GET_ACWAKELINE CS_IOR(6, unsigned int) +#define CS_SET_RX CS_IOW(7, struct hsi_rx_config) +#define CS_GET_RX CS_IOW(8, struct hsi_rx_config) +#define CS_SET_TX CS_IOW(9, struct hsi_tx_config) +#define CS_GET_TX CS_IOW(10, struct hsi_tx_config) +#define CS_SW_RESET CS_IO(11) +#define CS_GET_FIFO_OCCUPANCY CS_IOR(12, size_t) + +#define HSI_MODE_SLEEP 0 +#define HSI_MODE_STREAM 1 +#define HSI_MODE_FRAME 2 + +#define HSI_ARBMODE_RR 0 +#define HSI_ARBMODE_PRIO 1 + +#define WAKE_UP 1 +#define WAKE_DOWN 0 + +struct hsi_tx_config { + __u32 mode; + __u32 flow; + __u32 frame_size; + __u32 channels; + __u32 divisor; + __u32 arb_mode; +}; + +struct hsi_rx_config { + __u32 mode; + __u32 flow; + __u32 frame_size; + __u32 channels; + __u32 divisor; /* not used for SSI */ + __u32 counters; +}; + +#endif /* HSI_CHAR_H */ diff --git a/include/linux/hsi_driver_if.h b/include/linux/hsi_driver_if.h new file mode 100644 index 0000000..547b30e --- /dev/null +++ b/include/linux/hsi_driver_if.h @@ -0,0 +1,181 @@ +/* + * hsi_driver_if.h + * + * Header for the HSI driver low level interface. + * + * Copyright (C) 2007-2008 Nokia Corporation. All rights reserved. + * Copyright (C) 2009 Texas Instruments, Inc. + * + * Author: Carlos Chinea <carlos.chinea@nokia.com> + * Author: Sebastien JAN <s-jan@ti.com> + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef __HSI_DRIVER_IF_H__ +#define __HSI_DRIVER_IF_H__ + +#include <linux/platform_device.h> +#include <linux/device.h> +#include <linux/clk.h> +#include <linux/notifier.h> + +/* The number of ports handled by the driver (MAX:2). Reducing this value + * optimizes the driver memory footprint. + */ +#define HSI_MAX_PORTS 1 + +/* bit-field definition for allowed controller IDs and channels */ +#define ANY_HSI_CONTROLLER -1 + +/* HSR special divisor values set to control the auto-divisor Rx mode */ +#define HSI_HSR_DIVISOR_AUTO 0x1000 /* Activate auto Rx */ +#define HSI_SSR_DIVISOR_USE_TIMEOUT 0x1001 /* De-activate auto-Rx (SSI) */ + +enum { + HSI_EVENT_BREAK_DETECTED = 0, + HSI_EVENT_ERROR, + HSI_EVENT_PRE_SPEED_CHANGE, + HSI_EVENT_POST_SPEED_CHANGE, + HSI_EVENT_CAWAKE_UP, + HSI_EVENT_CAWAKE_DOWN, + HSI_EVENT_HSR_DATAAVAILABLE, +}; + +enum { + HSI_IOCTL_ACWAKE_DOWN = 0, /* Unset HST ACWAKE line for channel */ + HSI_IOCTL_ACWAKE_UP, /* Set HSI wakeup line (acwake) for channel */ + HSI_IOCTL_SEND_BREAK, /* Send a HW BREAK frame in FRAME mode */ + HSI_IOCTL_GET_ACWAKE, /* Get HST CAWAKE line status */ + HSI_IOCTL_FLUSH_RX, /* Force the HSR to idle state */ + HSI_IOCTL_FLUSH_TX, /* Force the HST to idle state */ + HSI_IOCTL_GET_CAWAKE, /* Get CAWAKE (HSR) line status */ + HSI_IOCTL_SET_RX, /* Set HSR configuration */ + HSI_IOCTL_GET_RX, /* Get HSR configuration */ + HSI_IOCTL_SET_TX, /* Set HST configuration */ + HSI_IOCTL_GET_TX, /* Get HST configuration */ + HSI_IOCTL_SW_RESET, /* Force a HSI SW RESET */ + HSI_IOCTL_GET_FIFO_OCCUPANCY, /* Get amount of words in RX FIFO */ + HSI_IOCTL_SET_ACREADY_SAFEMODE, + HSI_IOCTL_SET_ACREADY_NORMAL, + HSI_IOCTL_SET_3WIRE_MODE, + HSI_IOCTL_SET_4WIRE_MODE, +}; + +/* Forward references */ +struct hsi_device; +struct hsi_channel; + +/* DPS */ +struct hst_ctx { + u32 mode; + u32 flow; + u32 frame_size; + u32 divisor; + u32 arb_mode; + u32 channels; +}; + +struct hsr_ctx { + u32 mode; + u32 flow; + u32 frame_size; + u32 divisor; + u32 counters; + u32 channels; +}; + +struct port_ctx { + u32 sys_mpu_enable[2]; + struct hst_ctx hst; + struct hsr_ctx hsr; +}; + +/** + * struct ctrl_ctx - hsi controller regs context + * @sysconfig: keeps HSI_SYSCONFIG reg state + * @gdd_gcr: keeps DMA_GCR reg state + * @dll: keeps HSR_DLL state + * @pctx: array of port context + */ +struct ctrl_ctx { + u32 sysconfig; + u32 gdd_gcr; + u32 dll; + struct port_ctx *pctx; +}; +/* END DPS */ + + +/** + * struct hsi_device - HSI device object (Virtual) + * @n_ctrl: associated HSI controller platform id number + * @n_p: port number + * @n_ch: channel number + * @ch: channel descriptor + * @device: associated device +*/ +struct hsi_device { + int n_ctrl; + unsigned int n_p; + unsigned int n_ch; + struct hsi_channel *ch; + struct device device; +}; + +#define to_hsi_device(dev) container_of(dev, struct hsi_device, device) + +/** + * struct hsi_device_driver - HSI driver instance container + * @ctrl_mask: bit-field indicating the supported HSI device ids + * @ch_mask: bit-field indicating enabled channels for this port + * @probe: probe callback (driver registering) + * @remove: remove callback (driver un-registering) + * @suspend: suspend callback + * @resume: resume callback + * @driver: associated device_driver object +*/ +struct hsi_device_driver { + unsigned long ctrl_mask; + unsigned long ch_mask[HSI_MAX_PORTS]; + int (*probe) (struct hsi_device *dev); + int (*remove) (struct hsi_device *dev); + int (*suspend) (struct hsi_device *dev, pm_message_t mesg); + int (*resume) (struct hsi_device *dev); + struct device_driver driver; + void *priv_data; + +}; + +#define to_hsi_device_driver(drv) container_of(drv, \ + struct hsi_device_driver, \ + driver) + +int hsi_register_driver(struct hsi_device_driver *driver); +void hsi_unregister_driver(struct hsi_device_driver *driver); +int hsi_open(struct hsi_device *dev); +int hsi_write(struct hsi_device *dev, u32 * addr, unsigned int size); +int hsi_write_cancel(struct hsi_device *dev); +int hsi_read(struct hsi_device *dev, u32 * addr, unsigned int size); +int hsi_read_cancel(struct hsi_device *dev); +int hsi_poll(struct hsi_device *dev); +int hsi_unpoll(struct hsi_device *dev); +int hsi_ioctl(struct hsi_device *dev, unsigned int command, void *arg); +void hsi_close(struct hsi_device *dev); +void hsi_set_read_cb(struct hsi_device *dev, + void (*read_cb) (struct hsi_device *dev, + unsigned int size)); +void hsi_set_write_cb(struct hsi_device *dev, + void (*write_cb) (struct hsi_device *dev, + unsigned int size)); +void hsi_set_port_event_cb(struct hsi_device *dev, + void (*port_event_cb) (struct hsi_device *dev, + unsigned int event, + void *arg)); +#endif /* __HSI_DRIVER_IF_H__ */ diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index 7472449..3beb390 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -5,7 +5,7 @@ struct omap_i2c_bus_platform_data { u32 clkrate; - void (*set_mpu_wkup_lat)(struct device *dev, long set); + bool needs_wakeup_latency; int (*device_enable) (struct platform_device *pdev); int (*device_shutdown) (struct platform_device *pdev); int (*device_idle) (struct platform_device *pdev); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a6c652e..fd8fcf0 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -208,6 +208,7 @@ struct i2c_client { struct i2c_driver *driver; /* and our access routines */ struct device dev; /* the device structure */ int irq; /* irq issued by device */ + bool ext_master; /* determine if the dev has a master outside mpu */ struct list_head detected; }; #define to_i2c_client(d) container_of(d, struct i2c_client, dev) @@ -239,6 +240,7 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data) * @archdata: copied into i2c_client.dev.archdata * @of_node: pointer to OpenFirmware device node * @irq: stored in i2c_client.irq + * @ext_master: determine if the dev has a master outside mpu * * I2C doesn't actually support hardware probing, although controllers and * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's @@ -259,6 +261,7 @@ struct i2c_board_info { struct dev_archdata *archdata; struct device_node *of_node; int irq; + bool ext_master; }; /** @@ -370,6 +373,9 @@ struct i2c_adapter { struct mutex userspace_clients_lock; struct list_head userspace_clients; + + struct mutex ext_clients_lock; /* Lock for external clients list */ + struct list_head ext_clients; /* Clients with master from external proc */ }; #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) @@ -429,6 +435,7 @@ void i2c_unlock_adapter(struct i2c_adapter *); #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) extern int i2c_add_adapter(struct i2c_adapter *); extern int i2c_del_adapter(struct i2c_adapter *); +extern void i2c_detect_ext_master(struct i2c_adapter *); extern int i2c_add_numbered_adapter(struct i2c_adapter *); extern int i2c_register_driver(struct module *, struct i2c_driver *); diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index ba4f886..3c6e9a0 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -71,6 +71,7 @@ #define TWL4030_MODULE_PM_RECEIVER 0x15 #define TWL4030_MODULE_RTC 0x16 #define TWL4030_MODULE_SECURED_REG 0x17 +#define TWL6030_MODULE_SLAVE_RES 0x19 #define TWL_MODULE_USB TWL4030_MODULE_USB #define TWL_MODULE_AUDIO_VOICE TWL4030_MODULE_AUDIO_VOICE @@ -81,6 +82,7 @@ #define TWL_MODULE_PM_RECEIVER TWL4030_MODULE_PM_RECEIVER #define TWL_MODULE_RTC TWL4030_MODULE_RTC #define TWL_MODULE_PWM TWL4030_MODULE_PWM0 +#define TWL_MODULE_PM_SLAVE_RES TWL6030_MODULE_SLAVE_RES #define TWL6030_MODULE_ID0 0x0D #define TWL6030_MODULE_ID1 0x0E @@ -100,6 +102,7 @@ * Offset from TWL6030_IRQ_BASE / pdata->irq_base */ #define PWR_INTR_OFFSET 0 +#define TWL_VLOW_INTR_OFFSET 6 #define HOTDIE_INTR_OFFSET 12 #define SMPSLDO_INTR_OFFSET 13 #define BATDETECT_INTR_OFFSET 14 @@ -151,6 +154,8 @@ #define MMC_PU (0x1 << 3) #define MMC_PD (0x1 << 2) +#define VLOW_INT_MASK (0x1 << 2) + #define TWL_SIL_TYPE(rev) ((rev) & 0x00FFFFFF) #define TWL_SIL_REV(rev) ((rev) >> 24) #define TWL_SIL_5030 0x09002F @@ -450,6 +455,16 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) #define TWL4030_PM_MASTER_GLOBAL_TST 0xb6 +#define TWL6030_PHOENIX_DEV_ON 0x06 + +/* + * PM Slave resource module register offsets (use TWL6030_MODULE_SLAVE_RES) + */ + +#define REG_VBATMIN_HI_CFG_STATE 0x1D + +#define VBATMIN_VLOW_EN 0x21 + /*----------------------------------------------------------------------*/ /* Power bus message definitions */ @@ -522,6 +537,26 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) #define RES_MAIN_REF 28 #define TOTAL_RESOURCES 28 +/* 6030 extra resources */ +#define RES_V1V29 29 +#define RES_V1V8 30 +#define RES_V2V1 31 +#define RES_VDD3 32 +#define RES_VMEM 33 +#define RES_VANA 34 +#define RES_VUAX1 35 +#define RES_VCXIO 36 +#define RES_VPP 37 +#define RES_VRTC 38 +#define RES_REGEN2 39 +#define RES_32KCLKAO 40 +#define RES_32KCLKG 41 +#define RES_32KCLKAUDIO 42 +#define RES_BIAS 43 +#define RES_VBATMIN_HI 44 +#define RES_RC6MHZ 45 +#define RES_TEMP 46 + /* * Power Bus Message Format ... these can be sent individually by Linux, * but are usually part of downloaded scripts that are run when various @@ -641,21 +676,39 @@ struct twl4030_script { struct twl4030_resconfig { u8 resource; u8 devgroup; /* Processor group that Power resource belongs to */ + /* The following are used by TWL4030 only */ u8 type; /* Power resource addressed, 6 / broadcast message */ u8 type2; /* Power resource addressed, 3 / broadcast message */ u8 remap_off; /* off state remapping */ u8 remap_sleep; /* sleep state remapping */ }; +struct twl4030_system_config { + char *name; + u8 group; +}; + struct twl4030_power_data { - struct twl4030_script **scripts; - unsigned num; + struct twl4030_script **scripts; /* used in TWL4030 only */ + unsigned num; /* used in TWL4030 only */ struct twl4030_resconfig *resource_config; + struct twl4030_system_config *sys_config; /*system resources*/ #define TWL4030_RESCONFIG_UNDEF ((u8)-1) }; +#ifdef CONFIG_TWL4030_POWER extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts); extern int twl4030_remove_script(u8 flags); +#else +static inline void twl4030_power_init(struct twl4030_power_data *triton2_scripts) { } +static inline int twl4030_remove_script(u8 flags) { return -EINVAL; } +#endif + +#ifdef CONFIG_TWL6030_POWER +extern void twl6030_power_init(struct twl4030_power_data *power_data); +#else +extern inline void twl6030_power_init(struct twl4030_power_data *power_data) { } +#endif struct twl4030_codec_audio_data { unsigned int digimic_delay; /* in ms */ @@ -664,6 +717,11 @@ struct twl4030_codec_audio_data { unsigned int check_defaults:1; unsigned int reset_registers:1; unsigned int hs_extmute:1; + u16 hs_left_step; + u16 hs_right_step; + u16 hf_left_step; + u16 hf_right_step; + u16 ep_step; void (*set_hs_extmute)(int mute); }; @@ -679,6 +737,10 @@ struct twl4030_codec_data { /* twl6040 */ int audpwron_gpio; /* audio power-on gpio */ int naudint_irq; /* audio interrupt */ + unsigned int irq_base; + int (*get_ext_clk32k)(void); + void (*put_ext_clk32k)(void); + int (*set_ext_clk32k)(bool on); }; struct twl4030_platform_data { @@ -710,6 +772,10 @@ struct twl4030_platform_data { struct regulator_init_data *vintana1; struct regulator_init_data *vintana2; struct regulator_init_data *vintdig; + /* TWL6030 DCDC regulators */ + struct regulator_init_data *vdd3; + struct regulator_init_data *vmem; + struct regulator_init_data *v2v1; /* TWL6030 LDO regulators */ struct regulator_init_data *vmmc; struct regulator_init_data *vpp; @@ -718,6 +784,7 @@ struct twl4030_platform_data { struct regulator_init_data *vcxio; struct regulator_init_data *vusb; struct regulator_init_data *clk32kg; + struct regulator_init_data *clk32kaudio; /* TWL6025 LDO regulators */ struct regulator_init_data *ldo1; struct regulator_init_data *ldo2; @@ -829,5 +896,6 @@ static inline int twl4030charger_usb_en(int enable) { return 0; } #define TWL6025_REG_SMPS4 59 #define TWL6025_REG_VIO 60 +#define TWL6030_REG_CLK32KAUDIO 61 #endif /* End of __TWL4030_H */ diff --git a/include/linux/i2c/twl6030-madc.h b/include/linux/i2c/twl6030-madc.h new file mode 100644 index 0000000..81b9464 --- /dev/null +++ b/include/linux/i2c/twl6030-madc.h @@ -0,0 +1,86 @@ +/* + * twl6030_madc.h - Header for TWL6030 MADC + * + * Copyright (C) 2011 Samsung Telecommunications of America + * + * Based on twl4030-madc.h + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * J Keerthy <j-keerthy@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef _TWL6030_MADC_H +#define _TWL6030_MADC_H + +#define TWL6030_MADC_MAX_CHANNELS 17 +/* + * twl6030 madc occupies the same offset in the twl6030 map that + * twl4030 madc does in the twl4030 map. + * likewise the charger + */ +#define TWL6030_MODULE_MADC TWL4030_MODULE_MADC +#define TWL6030_MODULE_MAIN_CHARGE TWL4030_MODULE_MAIN_CHARGE + +#define TWL6030_MADC_CTRL 0x00 +#define TWL6030_MADC_TEMP1_EN (1 << 0) +#define TWL6030_MADC_TEMP2_EN (1 << 1) +#define TWL6030_MADC_SCALER_EN_CH2 (1 << 2) +#define TWL6030_MADC_VBAT_SCALER_DIV (1 << 3) +#define TWL6030_MADC_SCALER_EN_CH11 (1 << 4) +#define TWL6030_MADC_TMP1_EN_MONITOR (1 << 5) +#define TWL6030_MADC_TMP2_EN_MONITOR (1 << 6) +#define TWL6030_MADC_ISOURCE_EN (1 << 7) + +#define TWL6030_MADC_RTSELECT_LSB 0x02 +#define TWL6030_MADC_ADCIN0 (1 << 0) +#define TWL6030_MADC_ADCIN1 (1 << 1) +#define TWL6030_MADC_ADCIN2 (1 << 2) +#define TWL6030_MADC_ADCIN3 (1 << 3) +#define TWL6030_MADC_ADCIN4 (1 << 4) +#define TWL6030_MADC_ADCIN5 (1 << 5) +#define TWL6030_MADC_ADCIN6 (1 << 6) +#define TWL6030_MADC_ADCIN7 (1 << 7) + +#define TWL6030_MADC_RTSELECT_ISB 0x03 +#define TWL6030_MADC_ADCIN8 (1 << 0) +#define TWL6030_MADC_ADCIN9 (1 << 1) +#define TWL6030_MADC_ADCIN10 (1 << 2) +#define TWL6030_MADC_ADCIN11 (1 << 3) +#define TWL6030_MADC_ADCIN12 (1 << 4) +#define TWL6030_MADC_ADCIN13 (1 << 5) +#define TWL6030_MADC_ADCIN14 (1 << 6) +#define TWL6030_MADC_ADCIN15 (1 << 7) + +#define TWL6030_MADC_RTSELECT_MSB 0x04 +#define TWL6030_MADC_ADCIN16 (1 << 0) + +#define TWL6030_MADC_CTRL_P1 0x05 +#define TWL6030_MADC_BUSY (1 << 0) +#define TWL6030_MADC_EOCP1 (1 << 1) +#define TWL6030_MADC_EOCRT (1 << 2) +#define TWL6030_MADC_SP1 (1 << 3) + +#define TWL6030_MADC_CTRL_P2 0x06 +#define TWL6030_MADC_BUSYB (1 << 0) +#define TWL6030_MADC_EOCP2 (1 << 1) +#define TWL6030_MADC_SP2 (1 << 2) + +#define TWL6030_MADC_RTCH0_LSB 0x07 +#define TWL6030_MADC_GPCH0_LSB 0x29 + +int twl6030_get_madc_conversion(int channel_no); +#endif diff --git a/include/linux/mfd/twl6040-codec.h b/include/linux/mfd/twl6040-codec.h new file mode 100644 index 0000000..13ac335 --- /dev/null +++ b/include/linux/mfd/twl6040-codec.h @@ -0,0 +1,269 @@ +/* + * MFD driver for twl6040 codec submodule + * + * Authors: Jorge Eduardo Candelaria <jorge.candelaria@ti.com> + * Misael Lopez Cruz <misael.lopez@ti.com> + * + * Copyright: (C) 2011 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __TWL6040_CODEC_H__ +#define __TWL6040_CODEC_H__ + +#include <linux/interrupt.h> +#include <linux/mfd/core.h> + +#define TWL6040_NO_SUPPLY 0 +#define TWL6040_VIO_SUPPLY 1 +#define TWL6040_VDD_SUPPLY 2 + + +#define TWL6040_REG_ASICID 0x01 +#define TWL6040_REG_ASICREV 0x02 +#define TWL6040_REG_INTID 0x03 +#define TWL6040_REG_INTMR 0x04 +#define TWL6040_REG_NCPCTL 0x05 +#define TWL6040_REG_LDOCTL 0x06 +#define TWL6040_REG_HPPLLCTL 0x07 +#define TWL6040_REG_LPPLLCTL 0x08 +#define TWL6040_REG_LPPLLDIV 0x09 +#define TWL6040_REG_AMICBCTL 0x0A +#define TWL6040_REG_DMICBCTL 0x0B +#define TWL6040_REG_MICLCTL 0x0C +#define TWL6040_REG_MICRCTL 0x0D +#define TWL6040_REG_MICGAIN 0x0E +#define TWL6040_REG_LINEGAIN 0x0F +#define TWL6040_REG_HSLCTL 0x10 +#define TWL6040_REG_HSRCTL 0x11 +#define TWL6040_REG_HSGAIN 0x12 +#define TWL6040_REG_EARCTL 0x13 +#define TWL6040_REG_HFLCTL 0x14 +#define TWL6040_REG_HFLGAIN 0x15 +#define TWL6040_REG_HFRCTL 0x16 +#define TWL6040_REG_HFRGAIN 0x17 +#define TWL6040_REG_VIBCTLL 0x18 +#define TWL6040_REG_VIBDATL 0x19 +#define TWL6040_REG_VIBCTLR 0x1A +#define TWL6040_REG_VIBDATR 0x1B +#define TWL6040_REG_HKCTL1 0x1C +#define TWL6040_REG_HKCTL2 0x1D +#define TWL6040_REG_GPOCTL 0x1E +#define TWL6040_REG_ALB 0x1F +#define TWL6040_REG_DLB 0x20 +#define TWL6040_REG_TRIM1 0x28 +#define TWL6040_REG_TRIM2 0x29 +#define TWL6040_REG_TRIM3 0x2A +#define TWL6040_REG_HSOTRIM 0x2B +#define TWL6040_REG_HFOTRIM 0x2C +#define TWL6040_REG_ACCCTL 0x2D +#define TWL6040_REG_STATUS 0x2E + +#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1) + +#define TWL6040_VIOREGNUM 18 +#define TWL6040_VDDREGNUM 21 + +/* ASICREV (0x02) values */ + +#define TWL6040_REV_1_0 0x00 +#define TWL6040_REV_1_1 0x01 +#define TWL6040_REV_1_3 0x02 + +/* INTID (0x03) fields */ + +#define TWL6040_THINT 0x01 +#define TWL6040_PLUGINT 0x02 +#define TWL6040_UNPLUGINT 0x04 +#define TWL6040_HOOKINT 0x08 +#define TWL6040_HFINT 0x10 +#define TWL6040_VIBINT 0x20 +#define TWL6040_READYINT 0x40 + +/* INTMR (0x04) fields */ + +#define TWL6040_THMSK 0x01 +#define TWL6040_PLUGMSK 0x02 +#define TWL6040_HOOKMSK 0x08 +#define TWL6040_HFMSK 0x10 +#define TWL6040_VIBMSK 0x20 +#define TWL6040_READYMSK 0x40 +#define TWL6040_ALLINT_MSK 0x7B + +/* NCPCTL (0x05) fields */ + +#define TWL6040_NCPENA 0x01 +#define TWL6040_NCPOPEN 0x40 +#define TWL6040_TSHUTENA 0x80 + +/* LDOCTL (0x06) fields */ + +#define TWL6040_LSLDOENA 0x01 +#define TWL6040_HSLDOENA 0x04 +#define TWL6040_REFENA 0x40 +#define TWL6040_OSCENA 0x80 + +/* HPPLLCTL (0x07) fields */ + +#define TWL6040_HPLLENA 0x01 +#define TWL6040_HPLLRST 0x02 +#define TWL6040_HPLLBP 0x04 +#define TWL6040_HPLLSQRENA 0x08 +#define TWL6040_HPLLSQRBP 0x10 +#define TWL6040_MCLK_12000KHZ (0 << 5) +#define TWL6040_MCLK_19200KHZ (1 << 5) +#define TWL6040_MCLK_26000KHZ (2 << 5) +#define TWL6040_MCLK_38400KHZ (3 << 5) +#define TWL6040_MCLK_MSK 0x60 + +/* LPPLLCTL (0x08) fields */ + +#define TWL6040_LPLLENA 0x01 +#define TWL6040_LPLLRST 0x02 +#define TWL6040_LPLLSEL 0x04 +#define TWL6040_LPLLFIN 0x08 +#define TWL6040_HPLLSEL 0x10 + +/* HSLCTL (0x10) fields */ + +#define TWL6040_HSDACMODEL 0x02 +#define TWL6040_HSDRVMODEL 0x08 + +/* HSRCTL (0x11) fields */ + +#define TWL6040_HSDACMODER 0x02 +#define TWL6040_HSDRVMODER 0x08 + +/* VIBCTLL (0x18) fields */ + +#define TWL6040_VIBCTRLLN 0x10 +#define TWL6040_VIBCTRLLP 0x04 +#define TWL6040_VIBENAL 0x01 + +/* VIBCTLL (0x19) fields */ + +#define TWL6040_VIBCTRLRN 0x10 +#define TWL6040_VIBCTRLRP 0x04 +#define TWL6040_VIBENAR 0x01 + +/* GPOCTL (0x1E) fields */ + +#define TWL6040_GPO1 0x01 +#define TWL6040_GPO2 0x02 +#define TWL6040_GPO3 0x03 + +/* HSOTRIM (0x2B) fields */ + +#define TWL6040_HSLO 0x0F +#define TWL6040_HSRO 0xF0 +#define TWL6040_HSLO_OFFSET 0 +#define TWL6040_HSRO_OFFSET 4 + +/* HFOTRIM (0x2C) fields */ + +#define TWL6040_HFLO 0x0F +#define TWL6040_HFRO 0xF0 +#define TWL6040_HFLO_OFFSET 0 +#define TWL6040_HFRO_OFFSET 4 + +/* ACCCTL (0x2D) fields */ + +#define TWL6040_I2CSEL 0x01 +#define TWL6040_RESETSPLIT 0x04 +#define TWL6040_INTCLRMODE 0x08 +#define TWL6040_CLK32KSEL 0x40 + +/* STATUS (0x2E) fields */ + +#define TWL6040_PLUGCOMP 0x02 + +#define TWL6040_CELLS 2 + +#define TWL6040_IRQ_TH 0 +#define TWL6040_IRQ_PLUG 1 +#define TWL6040_IRQ_HOOK 2 +#define TWL6040_IRQ_HF 3 +#define TWL6040_IRQ_VIB 4 +#define TWL6040_IRQ_READY 5 + +enum twl6040_pll_id { + TWL6040_NOPLL_ID, + TWL6040_LPPLL_ID, + TWL6040_HPPLL_ID, +}; + +struct twl6040 { + struct device *dev; + struct mutex mutex; + struct mutex io_mutex; + struct mutex irq_mutex; + struct mfd_cell cells[TWL6040_CELLS]; + struct completion ready; + + int audpwron; + int powered; + int power_count; + + enum twl6040_pll_id pll; + unsigned int sysclk; + int icrev; + + unsigned int irq; + unsigned int irq_base; + u8 irq_masks_cur; + u8 irq_masks_cache; +}; + +static inline int twl6040_request_irq(struct twl6040 *twl6040, int irq, + irq_handler_t handler, const char *name, + void *data) +{ + if (!twl6040->irq_base) + return -EINVAL; + + return request_threaded_irq(twl6040->irq_base + irq, NULL, handler, + 0, name, data); +} + +static inline void twl6040_free_irq(struct twl6040 *twl6040, int irq, + void *data) +{ + if (!twl6040->irq_base) + return; + + free_irq(twl6040->irq_base + irq, data); +} + +int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg); +int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, + u8 val); +int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, + u8 mask); +int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, + u8 mask); +int twl6040_enable(struct twl6040 *twl6040); +int twl6040_disable(struct twl6040 *twl6040); +int twl6040_is_enabled(struct twl6040 *twl6040); +int twl6040_set_pll(struct twl6040 *twl6040, enum twl6040_pll_id id, + unsigned int freq_in, unsigned int freq_out); +enum twl6040_pll_id twl6040_get_pll(struct twl6040 *twl6040); +unsigned int twl6040_get_sysclk(struct twl6040 *twl6040); +int twl6040_get_icrev(struct twl6040 *twl6040); +int twl6040_irq_init(struct twl6040 *twl6040); +void twl6040_irq_exit(struct twl6040 *twl6040); + +#endif /* End of __TWL6040_CODEC_H__ */ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index ae28e93..561567e 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -533,4 +533,14 @@ struct isapnp_device_id { kernel_ulong_t driver_data; /* data private to the driver */ }; +/* rpmsg */ + +#define RPMSG_NAME_SIZE 32 +#define RPMSG_DEVICE_MODALIAS_FMT "rpmsg:%s" + +struct rpmsg_device_id { + char name[RPMSG_NAME_SIZE]; + kernel_ulong_t driver_data /* Data private to the driver */ + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/include/linux/omap_ion.h b/include/linux/omap_ion.h new file mode 100644 index 0000000..f73f127 --- /dev/null +++ b/include/linux/omap_ion.h @@ -0,0 +1,88 @@ +/* + * include/linux/omap_ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 _LINUX_OMAP_ION_H +#define _LINUX_OMAP_ION_H + +#include <linux/types.h> + +/** + * struct omap_ion_tiler_alloc_data - metadata passed from userspace for allocations + * @w: width of the allocation + * @h: height of the allocation + * @fmt: format of the data (8, 16, 32bit or page) + * @flags: flags passed to heap + * @stride: stride of the allocation, returned to caller from kernel + * @handle: pointer that will be populated with a cookie to use to refer + * to this allocation + * + * Provided by userspace as an argument to the ioctl + */ +struct omap_ion_tiler_alloc_data { + size_t w; + size_t h; + int fmt; + unsigned int flags; + struct ion_handle *handle; + size_t stride; + size_t offset; +}; + +#ifdef __KERNEL__ +int omap_ion_tiler_alloc(struct ion_client *client, + struct omap_ion_tiler_alloc_data *data); +int omap_ion_nonsecure_tiler_alloc(struct ion_client *client, + struct omap_ion_tiler_alloc_data *data); +/* given a handle in the tiler, return a list of tiler pages that back it */ +int omap_tiler_pages(struct ion_client *client, struct ion_handle *handle, + int *n, u32 ** tiler_pages); +#endif /* __KERNEL__ */ + +/* additional heaps used only on omap */ +enum { + OMAP_ION_HEAP_TYPE_TILER = ION_HEAP_TYPE_CUSTOM + 1, +}; + +#define OMAP_ION_HEAP_TILER_MASK (1 << OMAP_ION_HEAP_TYPE_TILER) + +enum { + OMAP_ION_TILER_ALLOC, +}; + +/** + * These should match the defines in the tiler driver + */ +enum { + TILER_PIXEL_FMT_MIN = 0, + TILER_PIXEL_FMT_8BIT = 0, + TILER_PIXEL_FMT_16BIT = 1, + TILER_PIXEL_FMT_32BIT = 2, + TILER_PIXEL_FMT_PAGE = 3, + TILER_PIXEL_FMT_MAX = 3 +}; + +/** + * List of heaps in the system + */ +enum { + OMAP_ION_HEAP_LARGE_SURFACES, + OMAP_ION_HEAP_TILER, + OMAP_ION_HEAP_SECURE_INPUT, + OMAP_ION_HEAP_NONSECURE_TILER, +}; + +#endif /* _LINUX_ION_H */ + diff --git a/include/linux/omap_v4l2_gfx.h b/include/linux/omap_v4l2_gfx.h new file mode 100644 index 0000000..cb175e5 --- /dev/null +++ b/include/linux/omap_v4l2_gfx.h @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + * This file specifies the custom ioctl API between a client "consumer" + * process and the V4L2-GFX driver. The consumer process should only use + * these APIs and will typically/ultimately be a GL application. + * + * There will also be a "producer" process which queues multimedia + * content to the driver, however, this will only use standard V4L2 APIs. + */ + +#ifndef _OMAP_V4L2_GFX_H_ +#define _OMAP_V4L2_GFX_H_ + +#include <linux/videodev.h> + +/* + * @see V4L2_GFX_IOC_CONSUMER, struct v4l2_gfx_consumer_params + */ +enum v4l2_gfx_consumer_type { + /* + * Wait for the producer process to activate a video stream + */ + V4L2_GFX_CONSUMER_WAITSTREAM, + }; + +/* + * @see V4L2_GFX_IOC_CONSUMER + */ +struct v4l2_gfx_consumer_params { + /* + * @see v4l2_gfx_consumer_type + */ + int type; /* w */ + /* + * If the consumer process is waiting the ioctl will block until the + * timeout expires or the expected event occurs, see the type field + */ + unsigned int timeout_ms; /* w */ + /* + * If acquire_timeout_ms > 0 and no streaming activity has been detected + * for acquire_timeout_ms milliseconds the V4L2_GFX_IOC_ACQ ioctl will + * return with ETIMEOUT + */ + unsigned int acquire_timeout_ms; /* w */ +}; + +/* + * @see V4L2_GFX_IOC_INFO + */ +struct v4l2_gfx_info_params { + + /* + * Return how many times the device has been opened, this number will + * decrement when the device is closed. + * + * One use for this might be to detect if a consumer or producer is + * active and in the process of setting up a stream. However this could + * be unreliable if the processes are in the process of closing / crashing. + * + * Obviously this value will always be at least one i.e. the process + * issuing the ioctl opens the device. + */ + unsigned int opencnt; /* r */ + +}; + +/* + * @see V4L2_GFX_IOC_PRODUCER + */ +struct v4l2_gfx_producer_params { + /* + * If set mark the producer side as open, if not set mark as closed. + * For Android we need this because the mediaserver won't close the + * driver. + */ + #define V4L2_GFX_PRODUCER_MASK_OPEN 0x1 + unsigned int flags; /* w */ +}; + +struct v4l2_gfx_buf_params { + /* + * Buffer index. + * + * On acquire, when the ioctl returns the bufid field will be filled in + * with the next buffer with data available. + * + * On release, the consumer process just specifies the buffer to release + * which usually is the last acquired buffer index. + */ + int bufid; /* r/w */ + + /* + * Cropping information + * For the acquire ioctl only + */ + int crop_top; /* r */ + int crop_left; /* r */ + int crop_width; /* r */ + int crop_height; /* r */ +}; + +/* + * This ioctl should be issued once by the consumer process before starting + * any rendering loop. It allows the process to wait for the producer process + * to become ready. + * + * @see struct v4l2_gfx_consumer_params + * + * Return value: + * Returns 0 if successful, or -1 on error, in which case errno indicates + * the error. + */ +#define V4L2_GFX_IOC_CONSUMER _IOWR ('v', BASE_VIDIOCPRIVATE+0, \ + struct v4l2_gfx_consumer_params) + +/* + * Acquire the buffer to be rendered and its properties. + * + * @see struct v4l2_gfx_buf_params + * + * Return value: + * Returns 0 if successful, or -1 on error, in which case errno indicates + * the error. + * + * ETIMEDOUT If acquire_timeout_ms is set via V4L2_GFX_IOC_CONSUMER + * this error code can be returned. + * ENODEV If the producer side of the stream stops this error will + * be returned. + */ +#define V4L2_GFX_IOC_ACQ _IOR ('v', BASE_VIDIOCPRIVATE+1, \ + struct v4l2_gfx_buf_params) + +/* + * Release the buffer that was rendered + * + * @see struct v4l2_gfx_buf_params + * + * Return value: + * Returns 0 if successful, or -1 on error, in which case errno indicates + * the error. + * + * ETIMEDOUT It took longer than 16ms for the app to render the frame + * (This will probably go away to avoid render loop stalls) + * EINVAL Attempted to release an invalid buffer index. + */ +#define V4L2_GFX_IOC_REL _IOW ('v', BASE_VIDIOCPRIVATE+2, \ + struct v4l2_gfx_buf_params) + +/* + * Ioctl used to get information about the device + * + * @see struct v4l2_gfx_info_params + * + * Return value: + * Returns 0 if successful, or -1 on error, in which case errno indicates + * the error. + */ +#define V4L2_GFX_IOC_INFO _IOWR ('v', BASE_VIDIOCPRIVATE+3, \ + struct v4l2_gfx_info_params) + +/* + * Ioctl used to set producer params + * + * @see struct v4l2_gfx_producer_params + * + * Return value: + * Returns 0 if successful, or -1 on error, in which case errno indicates + * the error. + */ +#define V4L2_GFX_IOC_PRODUCER _IOWR ('v', BASE_VIDIOCPRIVATE+4, \ + struct v4l2_gfx_producer_params) +#endif // _OMAP_V4L2_GFX_H_ diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h index c0b0187..80c5dc6 100644 --- a/include/linux/omapfb.h +++ b/include/linux/omapfb.h @@ -58,6 +58,7 @@ #define OMAPFB_GET_VRAM_INFO OMAP_IOR(61, struct omapfb_vram_info) #define OMAPFB_SET_TEARSYNC OMAP_IOW(62, struct omapfb_tearsync_info) #define OMAPFB_GET_DISPLAY_INFO OMAP_IOR(63, struct omapfb_display_info) +#define OMAPFB_ENABLEVSYNC OMAP_IOW(64, int) #define OMAPFB_CAPS_GENERIC_MASK 0x00000fff #define OMAPFB_CAPS_LCDC_MASK 0x00fff000 @@ -258,6 +259,16 @@ extern void omapfb_set_platform_data(struct omapfb_platform_data *data); extern void omapfb_set_ctrl_platform_data(void *pdata); extern void omapfb_reserve_sdram_memblock(void); +/* helper methods that may be used by other modules */ +enum omap_color_mode; +struct omap_video_timings; +int omapfb_mode_to_dss_mode(struct fb_var_screeninfo *var, + enum omap_color_mode *mode); +void omapfb_fb2dss_timings(struct fb_videomode *fb_timings, + struct omap_video_timings *dss_timings); +void omapfb_dss2fb_timings(struct omap_video_timings *dss_timings, + struct fb_videomode *fb_timings); + #endif #endif /* __OMAPFB_H */ diff --git a/include/linux/opp.h b/include/linux/opp.h index 5449945..7020e97 100644 --- a/include/linux/opp.h +++ b/include/linux/opp.h @@ -94,12 +94,20 @@ static inline int opp_disable(struct device *dev, unsigned long freq) #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP) int opp_init_cpufreq_table(struct device *dev, struct cpufreq_frequency_table **table); +void opp_free_cpufreq_table(struct device *dev, + struct cpufreq_frequency_table **table); #else static inline int opp_init_cpufreq_table(struct device *dev, struct cpufreq_frequency_table **table) { return -EINVAL; } + +static inline +void opp_free_cpufreq_table(struct device *dev, + struct cpufreq_frequency_table **table) +{ +} #endif /* CONFIG_CPU_FREQ */ #endif /* __LINUX_OPP_H__ */ diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h new file mode 100644 index 0000000..b7264e1 --- /dev/null +++ b/include/linux/remoteproc.h @@ -0,0 +1,311 @@ +/* + * Remote Processor Framework + * + * Copyright(c) 2011 Texas Instruments. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Texas Instruments nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef REMOTEPROC_H +#define REMOTEPROC_H + +#include <linux/mutex.h> +#include <linux/completion.h> +#include <linux/workqueue.h> +#include <linux/notifier.h> +#include <linux/pm_qos_params.h> + +/* Must match the BIOS version embeded in the BIOS firmware image */ +#define RPROC_BIOS_VERSION 2 + +/* Maximum number of entries that can be added for lookup */ +#define RPROC_MAX_MEM_ENTRIES 20 + +/** + * The following enums and structures define the binary format of the images + * we load and run the remote processors with. + * + * The binary format is as follows: + * + * struct { + * char magic[4] = { 'R', 'P', 'R', 'C' }; + * u32 version; + * u32 header_len; + * char header[...] = { header_len bytes of unformatted, textual header }; + * struct section { + * u32 type; + * u64 da; + * u32 len; + * u8 content[...] = { len bytes of binary data }; + * } [ no limit on number of sections ]; + * } __packed; + */ +struct fw_header { + char magic[4]; + u32 version; + u32 header_len; + char header[0]; +} __packed; + +struct fw_section { + u32 type; + u64 da; + u32 len; + char content[0]; +} __packed; + +enum fw_section_type { + FW_RESOURCE = 0, + FW_TEXT = 1, + FW_DATA = 2, + FW_MMU = 3, + FW_SIGNATURE = 4, +}; + +struct fw_resource { + u32 type; + u64 da; + u64 pa; + u32 len; + u32 reserved; + u8 name[48]; +} __packed; + +enum fw_resource_type { + RSC_CARVEOUT = 0, + RSC_DEVMEM = 1, + RSC_DEVICE = 2, + RSC_IRQ = 3, + RSC_TRACE = 4, + RSC_BOOTADDR = 5, + RSC_CRASHDUMP = 6, + RSC_END = 7, +}; + +/** + * struct rproc_mem_pool - descriptor for the rproc's contiguous memory pool data + * + * @mem_base: starting physical address of the dynamic pool + * @mem_size: size of the initial dynamic pool + * @cur_base: current available physical address in the pool + * @cur_size: remaining available memory in the pool + * @st_base: starting physical address of the static pool + * @st_size: size of the static pool + */ +struct rproc_mem_pool { + phys_addr_t mem_base; + u32 mem_size; + phys_addr_t cur_base; + u32 cur_size; + phys_addr_t st_base; + u32 st_size; +}; + +/** + * struct rproc_mem_entry - descriptor of a remote memory region + * + * @da: virtual address as seen by the device (aka device address) + * @pa: physical address + * @size: size of this memory region + */ +struct rproc_mem_entry { + u64 da; + phys_addr_t pa; + u32 size; + bool core; +}; + +enum rproc_constraint { + RPROC_CONSTRAINT_SCALE, + RPROC_CONSTRAINT_LATENCY, + RPROC_CONSTRAINT_BANDWIDTH, +}; + +struct rproc; + +struct rproc_ops { + int (*start)(struct rproc *rproc, u64 bootaddr); + int (*stop)(struct rproc *rproc); + int (*suspend)(struct rproc *rproc, bool force); + int (*resume)(struct rproc *rproc); + int (*iommu_init)(struct rproc *, int (*)(struct rproc *, u64, u32)); + int (*iommu_exit)(struct rproc *); + int (*set_lat)(struct rproc *rproc, long v); + int (*set_bw)(struct rproc *rproc, long v); + int (*scale)(struct rproc *rproc, long v); + int (*watchdog_init)(struct rproc *, int (*)(struct rproc *)); + int (*watchdog_exit)(struct rproc *); + void (*dump_registers)(struct rproc *); +}; + +/* + * enum rproc_state - remote processor states + * + * @RPROC_OFFLINE: needs firmware load and init to exit this state. + * + * @RPROC_SUSPENDED: needs to be woken up to receive a message. + * + * @RPROC_RUNNING: up and running. + * + * @RPROC_LOADING: asynchronous firmware loading has started + * + * @RPROC_CRASHED: needs to be logged, connections torn down, resources + * released, and returned to OFFLINE. + */ +enum rproc_state { + RPROC_OFFLINE, + RPROC_SUSPENDED, + RPROC_RUNNING, + RPROC_LOADING, + RPROC_CRASHED, +}; + +/* + * enum rproc_event - remote processor events + * + * @RPROC_ERROR: Fatal error has happened on the remote processor. + * + * @RPROC_PRE_SUSPEND: users can register for that event in order to cancel + * autosuspend, they just need to return an error in the + * callback function. + * + * @RPROC_POS_SUSPEND: users can register for that event in order to release + * resources not needed when the remote processor is + * sleeping or if they need to save some context. + * + * @RPROC_RESUME: users should use this event to revert what was done in the + * POS_SUSPEND event. + * + * @RPROC_SECURE: remote processor secure mode has changed. + */ +enum rproc_event { + RPROC_ERROR, + RPROC_PRE_SUSPEND, + RPROC_POS_SUSPEND, + RPROC_RESUME, + RPROC_SECURE, +}; + +#define RPROC_MAX_NAME 100 + +/* + * struct rproc - a physical remote processor device + * + * @next: next rproc entry in the list + * @name: human readable name of the rproc, cannot exceed RPROC_MAX_NAME bytes + * @memory_maps: table of da-to-pa memory maps (relevant if device is behind + * an iommu) + * @memory_pool: platform-specific contiguous memory pool data (relevant for + * allocating memory needed for the remote processor image) + * @firmware: name of firmware file to be loaded + * @owner: reference to the platform-specific rproc module + * @priv: private data which belongs to the platform-specific rproc module + * @ops: platform-specific start/stop rproc handlers + * @dev: reference to the platform-specific rproc dev + * @count: usage refcount + * @state: rproc_state enum value representing the state of the device + * @lock: lock which protects concurrent manipulations of the rproc + * @dbg_dir: debugfs directory of this rproc device + * @trace_buf0: main trace buffer of the remote processor + * @trace_buf1: second, optional, trace buffer of the remote processor + * @trace_len0: length of main trace buffer of the remote processor + * @trace_len1: length of the second (and optional) trace buffer + * @cdump_buf0: main exception/crash dump buffer of the remote processor + * @cdump_buf1: second exception/crash dump buffer of the remote processor + * @cdump_len0: length of main crash dump buffer of the remote processor + * @cdump_len1: length of the second (and optional) crash dump buffer + * @firmware_loading_complete: flags e/o asynchronous firmware loading + * @mmufault_work: work in charge of notifing mmufault + * @nb_error: notify block for fatal errors + * @error_comp: completion used when an error happens + * @secure_ttb: private data for configuring iommu in secure mode + * @secure_restart: completion event notifier for the secure restart process + * @secure_mode: flag to dictate whether to enable secure loading + * @secure_ok: restart status flag to be looked up upon the event's completion + */ +struct rproc { + struct list_head next; + const char *name; + struct rproc_mem_entry memory_maps[RPROC_MAX_MEM_ENTRIES]; + struct rproc_mem_pool *memory_pool; + const char *firmware; + struct module *owner; + void *priv; + const struct rproc_ops *ops; + struct device *dev; + int count; + int state; + struct mutex lock; + struct dentry *dbg_dir; + char *trace_buf0, *trace_buf1; + char *last_trace_buf0, *last_trace_buf1; + int trace_len0, trace_len1; + int last_trace_len0, last_trace_len1; + void *cdump_buf0, *cdump_buf1; + int cdump_len0, cdump_len1; + struct mutex tlock; + struct completion firmware_loading_complete; + struct work_struct error_work; + struct blocking_notifier_head nbh; + struct completion error_comp; +#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND + unsigned sus_timeout; + bool force_suspend; + bool need_resume; + struct mutex pm_lock; +#endif + struct pm_qos_request_list *qos_request; + void *secure_ttb; + struct completion secure_restart; + struct mutex secure_lock; + bool secure_mode; + bool secure_ok; + bool halt_on_crash; + char *header; + int header_len; +}; + +int rproc_set_secure(const char *, bool); +struct rproc *rproc_get(const char *); +void rproc_put(struct rproc *); +int rproc_event_register(struct rproc *, struct notifier_block *); +int rproc_event_unregister(struct rproc *, struct notifier_block *); +int rproc_register(struct device *, const char *, const struct rproc_ops *, + const char *, struct rproc_mem_pool *, struct module *, + unsigned int timeout); +int rproc_unregister(const char *); +void rproc_last_busy(struct rproc *); +#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND +extern const struct dev_pm_ops rproc_gen_pm_ops; +#define GENERIC_RPROC_PM_OPS (&rproc_gen_pm_ops) +#else +#define GENERIC_RPROC_PM_OPS NULL +#endif +int rproc_set_constraints(struct rproc *, enum rproc_constraint type, long v); +int rproc_error_notify(struct rproc *rproc); + +#endif /* REMOTEPROC_H */ diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h new file mode 100644 index 0000000..1f7ba09 --- /dev/null +++ b/include/linux/rpmsg.h @@ -0,0 +1,191 @@ +/* + * Remote processor messaging + * + * Copyright(c) 2011 Texas Instruments. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Texas Instruments nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LINUX_RPMSG_H +#define _LINUX_RPMSG_H + +#include <linux/types.h> +#include <linux/device.h> +#include <linux/mod_devicetable.h> + +/* The feature bitmap for virtio rpmsg */ +#define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */ + +/** + * struct rpmsg_hdr - + * + * ... keep documenting ... + */ +struct rpmsg_hdr { + u16 len; + u16 flags; + u32 src; + u32 dst; + u32 unused; + u8 data[0]; +} __packed; + +enum rpmsg_ns_flags { + RPMSG_NS_CREATE = 0, + RPMSG_NS_DESTROY = 1, +}; + +struct rpmsg_ns_msg { + char name[RPMSG_NAME_SIZE]; + u32 addr; + u32 flags; +} __packed; + +/* driver requests */ +enum { + VPROC_BUF_ADDR, + VPROC_BUF_NUM, + VPROC_BUF_SZ, + VPROC_SIM_BASE, + VPROC_STATIC_CHANNELS, +}; + +#define RPMSG_ADDR_ANY 0xFFFFFFFF + +struct virtproc_info; + +/** + * rpmsg_channel - rpmsg channels are the devices of the rpmsg bus + * + * @vrp: the remote processor this channel connects to + * @dev: underlying device + * @id: the device type identification (used to match an rpmsg driver) + * @src: local address of this channel + * @dst: destination address of the remote service + * @priv: private pointer for the driver's use. + * @ept: local rpmsg endpoint of this channel + * @announce: need to tell remoteproc about channel creation/removal + */ +struct rpmsg_channel { + struct virtproc_info *vrp; + struct device dev; + struct rpmsg_device_id id; + u32 src; + u32 dst; + void *priv; + struct rpmsg_endpoint *ept; + bool announce; +}; + +struct rpmsg_channel_info { + char name[RPMSG_NAME_SIZE]; + u32 src; + u32 dst; +}; + +/** + * struct rpmsg_endpoint + * + * @rpdev: + * @cb: + * @src: local rpmsg address + * @priv: + */ +struct rpmsg_endpoint { + struct rpmsg_channel *rpdev; + void (*cb)(struct rpmsg_channel *, void *, int, void *, u32); + u32 addr; + void *priv; +}; + +/** + * rpmsg_driver - operations for a rpmsg I/O driver + * @driver: underlying device driver (populate name and owner). + * @id_table: the ids serviced by this driver. + * @probe: the function to call when a device is found. Returns 0 or -errno. + * @remove: the function when a device is removed. + * @callback: invoked when a message is received on the channel + */ +struct rpmsg_driver { + struct device_driver drv; + const struct rpmsg_device_id *id_table; + int (*probe)(struct rpmsg_channel *dev); + void (*remove)(struct rpmsg_channel *dev); + void (*callback)(struct rpmsg_channel *, void *, int, void *, u32); +}; + +int register_rpmsg_device(struct rpmsg_channel *dev); +void unregister_rpmsg_device(struct rpmsg_channel *dev); +int register_rpmsg_driver(struct rpmsg_driver *drv); +void unregister_rpmsg_driver(struct rpmsg_driver *drv); +void rpmsg_destroy_ept(struct rpmsg_endpoint *); +struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *, + void (*cb)(struct rpmsg_channel *, void *, int, void *, u32), + void *priv, u32 addr); + +int +rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool); + +static inline +int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, + void *data, int len) +{ + return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); +} + +static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len) +{ + return rpmsg_send_offchannel(rpdev, rpdev->src, rpdev->dst, data, len); +} + +static inline +int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) +{ + return rpmsg_send_offchannel(rpdev, rpdev->src, dst, data, len); +} + +static inline +int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, + void *data, int len) +{ + return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); +} + +static inline +int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len) +{ + return rpmsg_trysend_offchannel(rpdev, rpdev->src, rpdev->dst, + data, len); +} + +static inline +int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) +{ + return rpmsg_trysend_offchannel(rpdev, rpdev->src, dst, data, len); +} + +#endif /* _LINUX_RPMSG_H */ diff --git a/include/linux/rpmsg_omx.h b/include/linux/rpmsg_omx.h new file mode 100644 index 0000000..15503d5 --- /dev/null +++ b/include/linux/rpmsg_omx.h @@ -0,0 +1,144 @@ +/* + * OMX offloading remote processor driver + * + * Copyright(c) 2011 Texas Instruments. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Texas Instruments nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RPMSG_OMX_H +#define RPMSG_OMX_H + +#include <linux/ioctl.h> + +#define OMX_IOC_MAGIC 'X' + +#define OMX_IOCCONNECT _IOW(OMX_IOC_MAGIC, 1, char *) +#define OMX_IOCIONREGISTER _IOWR(OMX_IOC_MAGIC, 2, struct ion_fd_data) +#define OMX_IOCIONUNREGISTER _IOWR(OMX_IOC_MAGIC, 3, struct ion_fd_data) + +#define OMX_IOC_MAXNR (3) + +#ifdef __KERNEL__ + +/** + * enum omx_msg_types - various message types currently supported + * + * @OMX_CONN_REQ: a connection request message type. the message should carry + * the name of the OMX service which we try to connect to. An instance of + * that service will be created remotely, and its address will be sent as + * a reply. + * + * @OMX_CONN_RSP: a response to a connection request. the message will carry + * an error code (success/failure), and if connection established successfully, + * the addr field will carry the address of the newly created OMX instance. + * + * @OMX_DISCONNECT: disconnect remote OMX instance. this message tells + * remote processor to release the resources coupled with this connection + * + * @OMX_RAW_MSG: a message that should be propagated as-is to the user. + * this would immediately enable user space development to start. + * as we progress, most likely this message won't be needed anymore. + */ +enum omx_msg_types { + OMX_CONN_REQ = 0, + OMX_CONN_RSP = 1, + OMX_DISCONNECT = 4, + OMX_RAW_MSG = 5, + /* todo: do we need a disconnect response ? ION refcounts should allow + * asynchronous release of relevant buffers */ +}; + +/** + * enum omx_error_codes - various error codes that will be used + * + * @OMX_SUCCESS: success + * + * @OMX_NOTSUPP: not supported + * + * @OMX_NOMEM: remote processor is out of memory + */ +enum omx_error_codes { + OMX_SUCCESS = 0, + OMX_NOTSUPP = 1, + OMX_NOMEM = 2, +}; + +/* keep documenting... */ +enum omx_state { + OMX_UNCONNECTED, + OMX_CONNECTED, + OMX_FAIL, +}; + +/** + * struct omx_msg_hdr - common header for all OMX messages + * @type: type of message, see enum omx_msg_types + * @flags: currently unused, should be zero + * @len: length of msg payload (in bytes) + * @data: the msg payload (depends on the message type) + * + * All OMX messages will start with this common header (which will begin + * right after the standard rpmsg header ends). + */ +struct omx_msg_hdr { + u32 type; + u32 flags; + u32 len; + char data[0]; +} __packed; + +struct omx_conn_rsp { + u32 status; + u32 addr; +} __packed; + +struct omx_disc_req { + u32 addr; +} __packed; + + +#endif /* __KERNEL__ */ + +/* temporarily exposed to user space too */ +struct omx_conn_req { + char name[48]; +} __packed; + +/* the packet structure (actual message sent to omx service) */ +struct omx_packet { + uint16_t desc; /* descriptor, and omx service status */ + uint16_t msg_id; /* message id */ + uint32_t flags; /* Set to a fixed value for now. */ + uint32_t fxn_idx; /* Index into OMX service's function table.*/ + int32_t result; /* The OMX function status. */ + uint32_t data_size;/* Size of in/out data to/from the function. */ + uint32_t data[0]; /* Payload of data_size char's passed to + function. */ +}; + +#endif /* RPMSG_OMX_H */ diff --git a/include/linux/rpmsg_resmgr.h b/include/linux/rpmsg_resmgr.h new file mode 100644 index 0000000..707809e --- /dev/null +++ b/include/linux/rpmsg_resmgr.h @@ -0,0 +1,131 @@ +/* + * Remote processor messaging + * + * Copyright(c) 2011 Texas Instruments. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Texas Instruments nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LINUX_RPMSG_RESMGR_H +#define _LINUX_RPMSG_RESMGR_H + +#define MAX_NUM_SDMA_CHANNELS 16 + +enum { + RPRM_GPTIMER = 0, + RPRM_IVAHD = 1, + RPRM_IVASEQ0 = 2, + RPRM_IVASEQ1 = 3, + RPRM_L3BUS = 4, + RPRM_ISS = 5, + RPRM_FDIF = 6, + RPRM_SL2IF = 7, + RPRM_AUXCLK = 8, + RPRM_REGULATOR = 9, + RPRM_GPIO = 10, + RPRM_SDMA = 11, + RPRM_IPU = 12, + RPRM_DSP = 13, + RPRM_I2C = 14, + RPRM_MAX +}; + +enum { + RPRM_CONNECT = 0, + RPRM_REQ_ALLOC = 1, + RPRM_REQ_FREE = 2, + RPRM_DISCONNECT = 3, + RPRM_REQ_CONSTRAINTS = 4, + RPRM_REL_CONSTRAINTS = 5, +}; + +enum { + RPRM_SCALE = 0x1, + RPRM_LATENCY = 0x2, + RPRM_BANDWIDTH = 0x4, +}; + +struct rprm_request { + u32 res_type; + u32 acquire; + u32 res_id; + char data[]; +} __packed; + +struct rprm_ack { + u32 ret; + u32 res_type; + u32 res_id; + u32 base; + char data[]; +} __packed; + +struct rprm_gpt { + u32 id; + u32 src_clk; +}; + +struct rprm_auxclk { + u32 id; + u32 clk_rate; + u32 parent_src_clk; + u32 parent_src_clk_rate; +}; + +struct rprm_regulator { + u32 id; + u32 min_uv; + u32 max_uv; +}; + +struct rprm_gpio { + u32 id; +}; + +/** + * struct rprm_i2c - resource i2c + * @id: i2c id + * + * meant to store the i2c related information + */ +struct rprm_i2c { + u32 id; +}; + +struct rprm_sdma { + u32 num_chs; + s32 channels[MAX_NUM_SDMA_CHANNELS]; +}; + +struct rprm_constraints_data { + u32 mask; + long frequency; + long bandwidth; + long latency; +}; + +#endif /* _LINUX_RPMSG_RESMGR_H */ diff --git a/include/linux/virtio_ids.h b/include/linux/virtio_ids.h index 85bb0bb..1520c06 100644 --- a/include/linux/virtio_ids.h +++ b/include/linux/virtio_ids.h @@ -35,5 +35,6 @@ #define VIRTIO_ID_RNG 4 /* virtio ring */ #define VIRTIO_ID_BALLOON 5 /* virtio balloon */ #define VIRTIO_ID_9P 9 /* 9p virtio console */ +#define VIRTIO_ID_RPMSG 10 /* virtio remote processor messaging */ #endif /* _LINUX_VIRTIO_IDS_H */ diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index 4a32cb6..7894a16 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h @@ -177,5 +177,7 @@ void vring_del_virtqueue(struct virtqueue *vq); void vring_transport_features(struct virtio_device *vdev); irqreturn_t vring_interrupt(int irq, void *_vq); +struct vring_virtqueue; +bool virtqueue_more_used(struct virtqueue *vq); #endif /* __KERNEL__ */ #endif /* _LINUX_VIRTIO_RING_H */ diff --git a/include/sound/omap-abe-dsp.h b/include/sound/omap-abe-dsp.h new file mode 100644 index 0000000..901a55c --- /dev/null +++ b/include/sound/omap-abe-dsp.h @@ -0,0 +1,21 @@ +/* + * omap-aess -- OMAP4 ABE DSP + * + * Author: Liam Girdwood <lrg@slimlogic.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _OMAP4_ABE_DSP_H +#define _OMAP4_ABE_DSP_H + +struct omap4_abe_dsp_pdata { + bool (*was_context_lost)(struct device *dev); + int (*device_scale)(struct device *req_dev, + struct device *target_dev, + unsigned long rate); +}; + +#endif diff --git a/include/sound/pcm.h b/include/sound/pcm.h index e1bad11..6a18765 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -413,6 +413,7 @@ struct snd_pcm_substream { #endif /* misc flags */ unsigned int hw_opened: 1; + unsigned int hw_no_buffer: 1; /* substream may not have a buffer */ }; #define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 1bafe95..bda171e 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -172,6 +172,8 @@ struct snd_soc_dai_ops { struct snd_soc_dai *); int (*trigger)(struct snd_pcm_substream *, int, struct snd_soc_dai *); + int (*bespoke_trigger)(struct snd_pcm_substream *, int, + struct snd_soc_dai *); /* * For hardware based FIFO caused delay reporting. * Optional. @@ -209,6 +211,10 @@ struct snd_soc_dai_driver { struct snd_soc_pcm_stream capture; struct snd_soc_pcm_stream playback; unsigned int symmetric_rates:1; + + /* probe ordering - for components with runtime dependencies */ + int probe_order; + int remove_order; }; /* @@ -277,4 +283,98 @@ static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai) return dev_get_drvdata(dai->dev); } +/* Backend DAI PCM ops */ +static inline int snd_soc_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int ret = 0; + + mutex_lock(&rtd->pcm_mutex); + + if (dai->driver->ops->startup) + ret = dai->driver->ops->startup(substream, dai); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dai->playback_active++; + else + dai->capture_active++; + + dai->active++; + + mutex_unlock(&rtd->pcm_mutex); + return ret; +} + +static inline void snd_soc_dai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + mutex_lock(&rtd->pcm_mutex); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dai->playback_active--; + else + dai->capture_active--; + + dai->active--; + + if (dai->driver->ops->shutdown) + dai->driver->ops->shutdown(substream, dai); + mutex_unlock(&rtd->pcm_mutex); +} + +static inline int snd_soc_dai_hw_params(struct snd_pcm_substream * substream, + struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int ret = 0; + + mutex_lock(&rtd->pcm_mutex); + + if (dai->driver->ops->hw_params) + ret = dai->driver->ops->hw_params(substream, hw_params, dai); + + mutex_unlock(&rtd->pcm_mutex); + return ret; +} + +static inline int snd_soc_dai_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int ret = 0; + + mutex_lock(&rtd->pcm_mutex); + + if (dai->driver->ops->hw_free) + ret = dai->driver->ops->hw_free(substream, dai); + + mutex_unlock(&rtd->pcm_mutex); + return ret; +} + +static inline int snd_soc_dai_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int ret = 0; + + mutex_lock(&rtd->pcm_mutex); + + if (dai->driver->ops->prepare) + ret = dai->driver->ops->prepare(substream, dai); + + mutex_unlock(&rtd->pcm_mutex); + return ret; +} + +static inline int snd_soc_dai_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + if (dai->driver->ops->trigger) + return dai->driver->ops->trigger(substream, cmd, dai); + return 0; +} #endif diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index c46e7d8..083f667 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -266,6 +266,12 @@ .get = snd_soc_dapm_get_enum_virt, \ .put = snd_soc_dapm_put_enum_virt, \ .private_value = (unsigned long)&xenum } +#define SOC_DAPM_ENUM_EXT(xname, xenum, xget, xput) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_enum_double, \ + .get = xget, \ + .put = xput, \ + .private_value = (unsigned long)&xenum } #define SOC_DAPM_VALUE_ENUM(xname, xenum) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_enum_double, \ @@ -310,6 +316,7 @@ struct snd_soc_dapm_path; struct snd_soc_dapm_pin; struct snd_soc_dapm_route; struct snd_soc_dapm_context; +struct snd_soc_dapm_widget_list; int dapm_reg_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); @@ -348,11 +355,25 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm); void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm); int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_route *route, int num); +int snd_soc_dapm_query_path(struct snd_soc_dapm_context *dapm, + const char *source_name, const char *sink_name, int stream); +const char *snd_soc_dapm_get_aif(struct snd_soc_dapm_context *dapm, + const char *stream_name, enum snd_soc_dapm_type type); /* dapm events */ +void snd_soc_dapm_platform_stream_event(struct snd_soc_platform *platform, + const char *stream, int event); +void snd_soc_dapm_codec_stream_event(struct snd_soc_codec *codec, + const char *stream, int event); int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, const char *stream, int event); void snd_soc_dapm_shutdown(struct snd_soc_card *card); +/* external DAPM widget events */ +int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, + struct snd_kcontrol *kcontrol, int connect); +int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget, + struct snd_kcontrol *kcontrol, int change, + int mux, struct soc_enum *e); /* dapm sys fs - used by the core */ int snd_soc_dapm_sys_add(struct device *dev); @@ -367,12 +388,21 @@ int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin); int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, const char *pin); +int snd_soc_dapm_get_pin_power(struct snd_soc_dapm_context *dapm, + const char *pin); int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm); int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin); int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, const char *pin); +/* dapm path query */ +int snd_soc_dapm_get_connected_widgets_type(struct snd_soc_dapm_context *dapm, + const char *stream_name, struct snd_soc_dapm_widget_list **list, + int stream, enum snd_soc_dapm_type type); +int snd_soc_dapm_get_connected_widgets_name(struct snd_soc_dapm_context *dapm, + const char *name, struct snd_soc_dapm_widget_list **list, int stream); + /* dapm widget types */ enum snd_soc_dapm_type { snd_soc_dapm_input = 0, /* input pin */ @@ -429,6 +459,7 @@ struct snd_soc_dapm_path { /* status */ u32 connect:1; /* source and sink widgets are connected */ u32 walked:1; /* path has been walked */ + u32 length:6; /* path length - used by route mapper */ int (*connected)(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink); @@ -444,6 +475,7 @@ struct snd_soc_dapm_widget { char *name; /* widget name */ char *sname; /* stream name */ struct snd_soc_codec *codec; + struct snd_soc_platform *platform; struct list_head list; struct snd_soc_dapm_context *dapm; @@ -452,6 +484,8 @@ struct snd_soc_dapm_widget { unsigned char shift; /* bits to shift */ unsigned int saved_value; /* widget saved value */ unsigned int value; /* widget current value */ + unsigned int path_idx; + unsigned int hops; unsigned int mask; /* non-shifted mask */ unsigned int on_val; /* on state value */ unsigned int off_val; /* off state value */ @@ -507,12 +541,17 @@ struct snd_soc_dapm_context { struct device *dev; /* from parent - for debug */ struct snd_soc_codec *codec; /* parent codec */ + struct snd_soc_platform *platform; /*parent platform */ struct snd_soc_card *card; /* parent card */ /* used during DAPM updates */ int dev_power; struct list_head list; + int num_valid_paths; + + int (*stream_event)(struct snd_soc_dapm_context *dapm); + #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_dapm; #endif diff --git a/include/sound/soc-dsp.h b/include/sound/soc-dsp.h new file mode 100644 index 0000000..033d61a --- /dev/null +++ b/include/sound/soc-dsp.h @@ -0,0 +1,128 @@ +/* + * linux/sound/soc-dsp.h -- ALSA SoC DSP + * + * Author: Liam Girdwood <lrg@slimlogic.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_SND_SOC_DSP_H +#define __LINUX_SND_SOC_DSP_H + +#include <sound/pcm.h> + +struct snd_soc_dapm_widget; + +/* + * Types of runtime_update to perform (e.g. originated from FE PCM ops + * or audio route changes triggered by muxes/mixers. + */ +#define SND_SOC_DSP_UPDATE_NO 0 +#define SND_SOC_DSP_UPDATE_BE 1 +#define SND_SOC_DSP_UPDATE_FE 2 + +/* + * DSP trigger ordering. Triggering flexibility is required as some DSPs + * require triggering before/after their clients/hosts. + * + * i.e. some clients may want to manually order this call in their PCM + * trigger() whilst others will just use the regular core ordering. + */ +enum snd_soc_dsp_trigger { + SND_SOC_DSP_TRIGGER_PRE = 0, + SND_SOC_DSP_TRIGGER_POST, + SND_SOC_DSP_TRIGGER_BESPOKE, +}; + +/* + * The DSP Frontend -> Backend link state. + */ +enum snd_soc_dsp_link_state { + SND_SOC_DSP_LINK_STATE_NEW = 0, /* newly created path */ + SND_SOC_DSP_LINK_STATE_FREE, /* path to be dismantled */ +}; + +struct snd_soc_dsp_params { + struct snd_soc_pcm_runtime *be; + struct snd_soc_pcm_runtime *fe; + enum snd_soc_dsp_link_state state; + struct list_head list_be; + struct list_head list_fe; + struct snd_pcm_hw_params hw_params; +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_state; +#endif +}; + +struct snd_soc_dsp_link { + bool capture; + bool playback; + enum snd_soc_dsp_trigger trigger[2]; +}; + +/* FE DSP PCM ops - called by soc-core */ +int soc_dsp_fe_dai_open(struct snd_pcm_substream *substream); +int soc_dsp_fe_dai_close(struct snd_pcm_substream *substream); +int soc_dsp_fe_dai_prepare(struct snd_pcm_substream *substream); +int soc_dsp_fe_dai_hw_free(struct snd_pcm_substream *substream); +int soc_dsp_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd); +int soc_dsp_fe_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params); + +/* Backend DSP trigger. + * Can be called by core or components depending on trigger config. + */ +int soc_dsp_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd); + +/* Is this trigger() call required for this FE and stream */ +static inline int snd_soc_dsp_is_trigger_for_fe(struct snd_soc_pcm_runtime *fe, + int stream) +{ + return (fe->dsp[stream].runtime_update == SND_SOC_DSP_UPDATE_FE); +} + +static inline int snd_soc_dsp_is_op_for_be(struct snd_soc_pcm_runtime *fe, + struct snd_soc_pcm_runtime *be, int stream) +{ + if ((fe->dsp[stream].runtime_update == SND_SOC_DSP_UPDATE_FE) || + ((fe->dsp[stream].runtime_update == SND_SOC_DSP_UPDATE_BE) && + be->dsp[stream].runtime_update)) + return 1; + else + return 0; +} + +static inline int snd_soc_dsp_platform_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_platform *platform) +{ + if (platform->driver->ops->trigger) + return platform->driver->ops->trigger(substream, cmd); + return 0; +} + +int soc_dsp_fe_state_count(struct snd_soc_pcm_runtime *be, int stream, + enum snd_soc_dsp_state state); + +/* Runtime update - open/close Backend DSP paths depending on mixer updates */ +int soc_dsp_runtime_update(struct snd_soc_dapm_widget *widget); + +/* Backend DSP suspend and resume */ +int soc_dsp_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute); +int soc_dsp_fe_suspend(struct snd_soc_pcm_runtime *fe); +int soc_dsp_be_ac97_cpu_dai_suspend(struct snd_soc_pcm_runtime *fe); +int soc_dsp_fe_resume(struct snd_soc_pcm_runtime *fe); +int soc_dsp_be_ac97_cpu_dai_resume(struct snd_soc_pcm_runtime *fe); + +/* DAPM stream events for Backend DSP paths */ +int soc_dsp_dapm_stream_event(struct snd_soc_pcm_runtime *fe, + int dir, const char *stream, int event); + +static inline struct snd_pcm_substream *snd_soc_dsp_get_substream( + struct snd_soc_pcm_runtime *be, int stream) +{ + return be->pcm->streams[stream].substream; +} + +#endif diff --git a/include/sound/soc.h b/include/sound/soc.h index 3a4bd3a..fa9f2ef 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -203,6 +203,24 @@ SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues) /* + * Component probe and remove ordering levels for components with runtime + * dependencies. + */ +#define SND_SOC_COMP_ORDER_FIRST -2 +#define SND_SOC_COMP_ORDER_EARLY -1 +#define SND_SOC_COMP_ORDER_NORMAL 0 +#define SND_SOC_COMP_ORDER_LATE 1 +#define SND_SOC_COMP_ORDER_LAST 2 + +/* DAI Link Host Mode Support */ +#define SND_SOC_DAI_LINK_NO_HOST 0x1 +#define SND_SOC_DAI_LINK_OPT_HOST 0x2 + +#define snd_soc_get_enum_text(soc_enum, idx) \ + (soc_enum->texts ? soc_enum->texts[idx] : soc_enum->dtexts[idx]) + + +/* * Bias levels * * @ON: Bias is fully on for audio playback and capture operations. @@ -220,6 +238,17 @@ enum snd_soc_bias_level { SND_SOC_BIAS_ON, }; +enum snd_soc_dsp_state { + SND_SOC_DSP_STATE_NEW = 0, + SND_SOC_DSP_STATE_OPEN, + SND_SOC_DSP_STATE_HW_PARAMS, + SND_SOC_DSP_STATE_PREPARE, + SND_SOC_DSP_STATE_START, + SND_SOC_DSP_STATE_STOP, + SND_SOC_DSP_STATE_HW_FREE, + SND_SOC_DSP_STATE_CLOSE, +}; + struct snd_jack; struct snd_soc_card; struct snd_soc_pcm_stream; @@ -237,6 +266,7 @@ struct snd_soc_jack; struct snd_soc_jack_zone; struct snd_soc_jack_pin; struct snd_soc_cache_ops; +struct snd_soc_dsp_link; #include <sound/soc-dapm.h> #ifdef CONFIG_GPIOLIB @@ -258,6 +288,11 @@ enum snd_soc_compress_type { SND_SOC_RBTREE_COMPRESSION }; +enum snd_soc_pcm_subclass { + SND_SOC_MUTEX_FE = 0, + SND_SOC_MUTEX_BE = 1, +}; + int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, unsigned int freq, int dir); int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, @@ -297,6 +332,18 @@ int snd_soc_default_readable_register(struct snd_soc_codec *codec, unsigned int reg); int snd_soc_default_writable_register(struct snd_soc_codec *codec, unsigned int reg); +unsigned int snd_soc_platform_read(struct snd_soc_platform *platform, + unsigned int reg); +unsigned int snd_soc_platform_write(struct snd_soc_platform *platform, + unsigned int reg, unsigned int val); + +struct snd_soc_codec *snd_soc_card_get_codec(struct snd_soc_card *card, + const char *codec_name); +struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, + const char *dai_link, int stream); +struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, + const char *dai_link); +int snd_soc_card_active_links(struct snd_soc_card *card); /* Utility functions to get clock rates from various things */ int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); @@ -349,6 +396,8 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, const char *prefix); int snd_soc_add_controls(struct snd_soc_codec *codec, const struct snd_kcontrol_new *controls, int num_controls); +int snd_soc_add_platform_controls(struct snd_soc_platform *platform, + const struct snd_kcontrol_new *controls, int num_controls); int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol, @@ -612,6 +661,13 @@ struct snd_soc_codec_driver { void (*seq_notifier)(struct snd_soc_dapm_context *, enum snd_soc_dapm_type, int); + + /* probe ordering - for components with runtime dependencies */ + int probe_order; + int remove_order; + + /* codec stream completion event */ + int (*stream_event)(struct snd_soc_dapm_context *dapm); }; /* SoC platform interface */ @@ -623,8 +679,7 @@ struct snd_soc_platform_driver { int (*resume)(struct snd_soc_dai *dai); /* pcm creation and destruction */ - int (*pcm_new)(struct snd_card *, struct snd_soc_dai *, - struct snd_pcm *); + int (*pcm_new)(struct snd_soc_pcm_runtime *); void (*pcm_free)(struct snd_pcm *); /* @@ -636,6 +691,17 @@ struct snd_soc_platform_driver { /* platform stream ops */ struct snd_pcm_ops *ops; + + /* probe ordering - for components with runtime dependencies */ + int probe_order; + int remove_order; + + int (*stream_event)(struct snd_soc_dapm_context *dapm); + int (*bespoke_trigger)(struct snd_pcm_substream *, int); + + /* platform DAPM IO TODO: refactor this */ + unsigned int (*read)(struct snd_soc_platform *, unsigned int); + int (*write)(struct snd_soc_platform *, unsigned int, unsigned int); }; struct snd_soc_platform { @@ -647,9 +713,19 @@ struct snd_soc_platform { unsigned int suspended:1; /* platform is suspended */ unsigned int probed:1; + struct snd_card *snd_card; struct snd_soc_card *card; struct list_head list; struct list_head card_list; + int num_dai; + + /* dapm */ + struct snd_soc_dapm_context dapm; + +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_platform_root; + struct dentry *debugfs_dapm; +#endif }; struct snd_soc_dai_link { @@ -661,15 +737,32 @@ struct snd_soc_dai_link { const char *cpu_dai_name; const char *codec_dai_name; + struct snd_soc_dsp_link *dsp_link; /* Keep DAI active over suspend */ unsigned int ignore_suspend:1; /* Symmetry requirements */ unsigned int symmetric_rates:1; + /* No PCM created for this DAI link */ + unsigned int no_pcm:1; + /* This DAI link can change CODEC and platform at runtime*/ + unsigned int dynamic:1; + /* This DAI link has no codec side driver*/ + unsigned int no_codec:1; + /* This DAI has a Backend ID */ + unsigned int be_id; + /* This DAI can support no host IO (no pcm data is copied to from host) */ + unsigned int no_host_mode:2; + /* DAI link active */ + unsigned int active; /* codec/machine specific init - e.g. add machine controls */ int (*init)(struct snd_soc_pcm_runtime *rtd); + /* hw_params re-writing for BE and FE sync */ + int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); + /* machine stream operations */ struct snd_soc_ops *ops; }; @@ -709,6 +802,9 @@ struct snd_soc_card { struct list_head list; struct mutex mutex; + struct mutex dapm_mutex; + struct mutex dsp_mutex; + struct mutex power_mutex; bool instantiated; @@ -774,6 +870,7 @@ struct snd_soc_card { /* Generic DAPM context for the card */ struct snd_soc_dapm_context dapm; + int (*stream_event)(struct snd_soc_dapm_context *dapm); #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_card_root; @@ -784,15 +881,32 @@ struct snd_soc_card { void *drvdata; }; +/* DSP runtime data */ +struct snd_soc_dsp_runtime { + struct list_head be_clients; + struct list_head fe_clients; + int users; + struct snd_pcm_runtime *runtime; + struct snd_pcm_hw_params hw_params; + int runtime_update; + enum snd_soc_dsp_state state; +}; + /* SoC machine DAI configuration, glues a codec and cpu DAI together */ struct snd_soc_pcm_runtime { struct device dev; struct snd_soc_card *card; struct snd_soc_dai_link *dai_link; + struct mutex pcm_mutex; + enum snd_soc_pcm_subclass pcm_subclass; + struct snd_pcm_ops ops; unsigned int complete:1; unsigned int dev_registered:1; + /* DSP runtime data */ + struct snd_soc_dsp_runtime dsp[2]; + /* Symmetry data - only valid if symmetry is being enforced */ unsigned int rate; long pmdown_time; @@ -805,6 +919,11 @@ struct snd_soc_pcm_runtime { struct snd_soc_dai *cpu_dai; struct delayed_work delayed_work; + +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_dsp_root; + struct dentry *debugfs_dsp_state; +#endif }; /* mixer control */ @@ -822,6 +941,7 @@ struct soc_enum { unsigned int max; unsigned int mask; const char * const *texts; + char **dtexts; const unsigned int *values; void *dapm; }; diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h index ae973d2..603f5a0 100644 --- a/include/trace/events/asoc.h +++ b/include/trace/events/asoc.h @@ -9,6 +9,7 @@ struct snd_soc_jack; struct snd_soc_codec; +struct snd_soc_platform; struct snd_soc_card; struct snd_soc_dapm_widget; @@ -59,6 +60,50 @@ DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, ); +DECLARE_EVENT_CLASS(snd_soc_preg, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val), + + TP_STRUCT__entry( + __string( name, platform->name ) + __field( int, id ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + __assign_str(name, platform->name); + __entry->id = platform->id; + __entry->reg = reg; + __entry->val = val; + ), + + TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), + (int)__entry->id, (unsigned int)__entry->reg, + (unsigned int)__entry->val) +); + +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val) + +); + +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val) + +); + DECLARE_EVENT_CLASS(snd_soc_card, TP_PROTO(struct snd_soc_card *card, int val), diff --git a/include/video/dsscomp.h b/include/video/dsscomp.h new file mode 100644 index 0000000..4fdcb0c --- /dev/null +++ b/include/video/dsscomp.h @@ -0,0 +1,644 @@ +#ifndef _LINUX_DSSCOMP_H +#define _LINUX_DSSCOMP_H + +#ifdef __KERNEL__ +#include <video/omapdss.h> +#else + +/* exporting enumerations from arch/arm/plat-omap/include/plat/display.h */ +enum omap_plane { + OMAP_DSS_GFX = 0, + OMAP_DSS_VIDEO1 = 1, + OMAP_DSS_VIDEO2 = 2, + OMAP_DSS_VIDEO3 = 3, + OMAP_DSS_WB = 4, +}; + +enum omap_channel { + OMAP_DSS_CHANNEL_LCD = 0, + OMAP_DSS_CHANNEL_DIGIT = 1, + OMAP_DSS_CHANNEL_LCD2 = 2, +}; + +enum omap_color_mode { + OMAP_DSS_COLOR_CLUT1 = 1 << 0, /* BITMAP 1 */ + OMAP_DSS_COLOR_CLUT2 = 1 << 1, /* BITMAP 2 */ + OMAP_DSS_COLOR_CLUT4 = 1 << 2, /* BITMAP 4 */ + OMAP_DSS_COLOR_CLUT8 = 1 << 3, /* BITMAP 8 */ + + /* also referred to as RGB 12-BPP, 16-bit container */ + OMAP_DSS_COLOR_RGB12U = 1 << 4, /* xRGB12-4444 */ + OMAP_DSS_COLOR_ARGB16 = 1 << 5, /* ARGB16-4444 */ + OMAP_DSS_COLOR_RGB16 = 1 << 6, /* RGB16-565 */ + + /* also referred to as RGB 24-BPP, 32-bit container */ + OMAP_DSS_COLOR_RGB24U = 1 << 7, /* xRGB24-8888 */ + OMAP_DSS_COLOR_RGB24P = 1 << 8, /* RGB24-888 */ + OMAP_DSS_COLOR_YUV2 = 1 << 9, /* YUV2 4:2:2 co-sited */ + OMAP_DSS_COLOR_UYVY = 1 << 10, /* UYVY 4:2:2 co-sited */ + OMAP_DSS_COLOR_ARGB32 = 1 << 11, /* ARGB32-8888 */ + OMAP_DSS_COLOR_RGBA32 = 1 << 12, /* RGBA32-8888 */ + + /* also referred to as RGBx 32 in TRM */ + OMAP_DSS_COLOR_RGBX24 = 1 << 13, /* RGBx32-8888 */ + OMAP_DSS_COLOR_RGBX32 = 1 << 13, /* RGBx32-8888 */ + OMAP_DSS_COLOR_NV12 = 1 << 14, /* NV12 format: YUV 4:2:0 */ + + /* also referred to as RGBA12-4444 in TRM */ + OMAP_DSS_COLOR_RGBA16 = 1 << 15, /* RGBA16-4444 */ + + OMAP_DSS_COLOR_RGBX12 = 1 << 16, /* RGBx16-4444 */ + OMAP_DSS_COLOR_RGBX16 = 1 << 16, /* RGBx16-4444 */ + OMAP_DSS_COLOR_ARGB16_1555 = 1 << 17, /* ARGB16-1555 */ + + /* also referred to as xRGB16-555 in TRM */ + OMAP_DSS_COLOR_XRGB15 = 1 << 18, /* xRGB16-1555 */ + OMAP_DSS_COLOR_XRGB16_1555 = 1 << 18, /* xRGB16-1555 */ +}; + +enum omap_dss_trans_key_type { + OMAP_DSS_COLOR_KEY_GFX_DST = 0, + OMAP_DSS_COLOR_KEY_VID_SRC = 1, +}; + +enum omap_dss_display_state { + OMAP_DSS_DISPLAY_DISABLED = 0, + OMAP_DSS_DISPLAY_ACTIVE, + OMAP_DSS_DISPLAY_SUSPENDED, + OMAP_DSS_DISPLAY_TRANSITION, +}; + +struct omap_video_timings { + /* Unit: pixels */ + __u16 x_res; + /* Unit: pixels */ + __u16 y_res; + /* Unit: KHz */ + __u32 pixel_clock; + /* Unit: pixel clocks */ + __u16 hsw; /* Horizontal synchronization pulse width */ + /* Unit: pixel clocks */ + __u16 hfp; /* Horizontal front porch */ + /* Unit: pixel clocks */ + __u16 hbp; /* Horizontal back porch */ + /* Unit: line clocks */ + __u16 vsw; /* Vertical synchronization pulse width */ + /* Unit: line clocks */ + __u16 vfp; /* Vertical front porch */ + /* Unit: line clocks */ + __u16 vbp; /* Vertical back porch */ +}; + +/* YUV to RGB color conversion info */ +struct omap_dss_cconv_coefs { + __s16 ry, rcr, rcb; + __s16 gy, gcr, gcb; + __s16 by, bcr, bcb; + + /* Y is 16..235, UV is 16..240 if not fullrange. Otherwise 0..255 */ + __u16 full_range; +} __attribute__ ((aligned(4))); + +struct omap_dss_cpr_coefs { + __s16 rr, rg, rb; + __s16 gr, gg, gb; + __s16 br, bg, bb; +}; + +#endif + +/* copy of fb_videomode */ +struct dsscomp_videomode { + const char *name; /* optional */ + __u32 refresh; /* optional */ + __u32 xres; + __u32 yres; + __u32 pixclock; + __u32 left_margin; + __u32 right_margin; + __u32 upper_margin; + __u32 lower_margin; + __u32 hsync_len; + __u32 vsync_len; + __u32 sync; + __u32 vmode; + __u32 flag; +}; + +/* + * Stereoscopic Panel types + * row, column, overunder, sidebyside options + * are with respect to native scan order + */ +enum s3d_disp_type { + S3D_DISP_NONE = 0, + S3D_DISP_FRAME_SEQ, + S3D_DISP_ROW_IL, + S3D_DISP_COL_IL, + S3D_DISP_PIX_IL, + S3D_DISP_CHECKB, + S3D_DISP_OVERUNDER, + S3D_DISP_SIDEBYSIDE, +}; + +/* Subsampling direction is based on native panel scan order.*/ +enum s3d_disp_sub_sampling { + S3D_DISP_SUB_SAMPLE_NONE = 0, + S3D_DISP_SUB_SAMPLE_V, + S3D_DISP_SUB_SAMPLE_H, +}; + +/* + * Indicates if display expects left view first followed by right or viceversa + * For row interlaved displays, defines first row view + * For column interleaved displays, defines first column view + * For checkerboard, defines first pixel view + * For overunder, defines top view + * For sidebyside, defines west view + */ +enum s3d_disp_order { + S3D_DISP_ORDER_L = 0, + S3D_DISP_ORDER_R = 1, +}; + +/* + * Indicates current view + * Used mainly for displays that need to trigger a sync signal + */ +enum s3d_disp_view { + S3D_DISP_VIEW_L = 0, + S3D_DISP_VIEW_R, +}; + +struct s3d_disp_info { + enum s3d_disp_type type; + enum s3d_disp_sub_sampling sub_samp; + enum s3d_disp_order order; + /* + * Gap between left and right views + * For over/under units are lines + * For sidebyside units are pixels + * For other types ignored + */ + unsigned int gap; +}; + +enum omap_dss_ilace_mode { + OMAP_DSS_ILACE = (1 << 0), /* interlaced vs. progressive */ + OMAP_DSS_ILACE_SEQ = (1 << 1), /* sequential vs interleaved */ + OMAP_DSS_ILACE_SWAP = (1 << 2), /* swap fields, e.g. TB=>BT */ + + OMAP_DSS_ILACE_NONE = 0, + OMAP_DSS_ILACE_IL_TB = OMAP_DSS_ILACE, + OMAP_DSS_ILACE_IL_BT = OMAP_DSS_ILACE | OMAP_DSS_ILACE_SWAP, + OMAP_DSS_ILACE_SEQ_TB = OMAP_DSS_ILACE_IL_TB | OMAP_DSS_ILACE_SEQ, + OMAP_DSS_ILACE_SEQ_BT = OMAP_DSS_ILACE_IL_BT | OMAP_DSS_ILACE_SEQ, +}; + +/* YUV VC1 range mapping info */ +struct dss2_vc1_range_map_info { + __u8 enable; /* bool */ + + __u8 range_y; /* 0..7 */ + __u8 range_uv; /* 0..7 */ +} __attribute__ ((aligned(4))); + +/* standard rectangle */ +struct dss2_rect_t { + __s32 x; /* left */ + __s32 y; /* top */ + __u32 w; /* width */ + __u32 h; /* height */ +} __attribute__ ((aligned(4))); + +/* decimation constraints */ +struct dss2_decim { + __u8 min_x; + __u8 max_x; /* 0 is same as 255 */ + __u8 min_y; + __u8 max_y; /* 0 is same as 255 */ +} __attribute__ ((aligned(4))); + +/* + * A somewhat more user friendly interface to the DSS2. This is a + * direct interface to the DSS2 overlay and overlay_manager modules. + * User-space APIs are provided for HW-specific control of DSS in + * contrast with V4L2/FB that are more generic, but in this process + * omit HW-specific features. + * + * For now managers are specified by display index as opposed to manager + * type, so that display0 is always the default display (e.g. HDMI on + * panda, and LCD blaze.) For now you would need to query the displays + * or use sysfs to find a specific display. + * + * Userspace operations are as follows: + * + * 1) check if DSS supports an overlay configuration, use DSSCIOC_CHECK_OVL + * ioctl with the manager, overlay, and setup-mode information filled out. + * All fields should be filled out as it may influence whether DSS can + * display/render the overlay. + * + * If proper address information is not available, it may be possible to + * use a type-of-address enumeration instead for luma/rgb and chroma (if + * applicable) frames. + * + * Do this for each overlay before attempting to configure DSS. + * + * 2) configure DSS pipelines for display/manager using DSSCOMP_SETUP_MANAGER + * ioctl. You can delay applying the settings until an dss2_manager_apply() + * is called for the internal composition object, if the APPLY bit of setup mode + * is not set. However the CAPTURE/DISPLAY bits of the setup mode settings will + * determine if at this time a capture will take place (in case of capture + * only mode). You may also set up additional pipelines with + * dss2_overlay_setup() before this. + * + * 3) On OMAP4/5 you can use the DSS WB pipeline to copy (and convert) a buffer + * using DSS. Use the DSSCIOC_WB_COPY ioctl for this. This is a blocking + * call, and it may possibly fail if an ongoing WB capture mode has been + * scheduled (which is outside of the current scope of the DSS2 interface.) + * + * There is also a one-shot configuration API (DSSCIOC_SETUP_DISPC). This + * allows you to set-up all overlays on all managers in one call. This call + * performs additional functionality: + * + * - it maps userspace 1D buffers into TILER 1D for the duration of the display + * - it disables all overlays that were specified before, but are no longer + * specified + * + */ + +/* + * DSS2 overlay information. This structure contains all information + * needed to set up the overlay for a particular buffer to be displayed + * at a particular orientation. + * + * The following information is deemed to be set globally, so it is not + * included: + * - whether to enable zorder (always enabled) + * - whether to replicate/truncate color fields (it is decided per the + * whole manager/overlay settings, and is enabled unless overlay is + * directed to WB.) + * + * There is also no support for CLUT formats + * + * Requirements: + * + * 1) 0 <= crop.x <= crop.x + crop.w <= width + * 2) 0 <= crop.y <= crop.y + crop.h <= height + * 3) win.x <= win.x + win.w and win.w >= 0 + * 4) win.y <= win.y + win.h and win.h >= 0 + * + * 5) color_mode is supported by overlay + * 6) requested scaling is supported by overlay and functional clocks + * + * Notes: + * + * 1) Any portions of X:[pos_x, pos_x + out_width] and + * Y:[pos_y, pos_y + out_height] outside of the screen + * X:[0, screen.width], Y:[0, screen.height] will be cropped + * automatically without changing the scaling ratio. + * + * 2) Crop region will be adjusted to the pixel granularity: + * (2-by-1) for YUV422, (2-by-2) for YUV420. This will + * not modify the output region. Crop region is for the + * original (unrotated) buffer, so it does not change with + * rotation. + * + * 3) Rotation will not modify the output region, specifically + * its height and width. Also the coordinate system of the + * display is always (0,0) = top left. + * + * 4) cconv and vc1 only needs to be filled for YUV color modes. + * + * 5) vc1.range_y and vc1.range_uv only needs to be filled if + * vc1.enable is true. + */ +struct dss2_ovl_cfg { + __u16 width; /* buffer width */ + __u16 height; /* buffer height */ + __u32 stride; /* buffer stride */ + + enum omap_color_mode color_mode; + __u8 pre_mult_alpha; /* bool */ + __u8 global_alpha; /* 0..255 */ + __u8 rotation; /* 0..3 (*90 degrees clockwise) */ + __u8 mirror; /* left-to-right: mirroring is applied after rotation */ + + enum omap_dss_ilace_mode ilace; /* interlace mode */ + + struct dss2_rect_t win; /* output window - on display */ + struct dss2_rect_t crop; /* crop window - in source buffer */ + + struct dss2_decim decim; /* predecimation limits */ + + struct omap_dss_cconv_coefs cconv; + struct dss2_vc1_range_map_info vc1; + + __u8 ix; /* ovl index same as sysfs/overlay# */ + __u8 zorder; /* 0..3 */ + __u8 enabled; /* bool */ + __u8 zonly; /* only set zorder and enabled bit */ + __u8 mgr_ix; /* mgr index */ +} __attribute__ ((aligned(4))); + +enum omapdss_buffer_type { + OMAP_DSS_BUFTYPE_SDMA, + OMAP_DSS_BUFTYPE_TILER_8BIT, + OMAP_DSS_BUFTYPE_TILER_16BIT, + OMAP_DSS_BUFTYPE_TILER_32BIT, + OMAP_DSS_BUFTYPE_TILER_PAGE, +}; + +enum omapdss_buffer_addressing_type { + OMAP_DSS_BUFADDR_DIRECT, /* using direct addresses */ + OMAP_DSS_BUFADDR_BYTYPE, /* using buffer types */ + OMAP_DSS_BUFADDR_ION, /* using ion handle(s) */ + OMAP_DSS_BUFADDR_GRALLOC, /* using gralloc handle */ + OMAP_DSS_BUFADDR_OVL_IX, /* using a prior overlay */ + OMAP_DSS_BUFADDR_LAYER_IX, /* using a Post2 layer */ + OMAP_DSS_BUFADDR_FB, /* using framebuffer memory */ +}; + +struct dss2_ovl_info { + struct dss2_ovl_cfg cfg; + + enum omapdss_buffer_addressing_type addressing; + + union { + /* user-space interfaces */ + struct { + void *address; /* main buffer address */ + void *uv_address; /* uv buffer */ + }; + + /* + * For DSSCIOC_CHECK_OVL we allow specifying just the + * type of each buffer. This is used if we need to + * check whether DSS will be able to display a buffer + * if using a particular memory type before spending + * time to map/copy the buffer into that type of + * memory. + */ + struct { + enum omapdss_buffer_type ba_type; + enum omapdss_buffer_type uv_type; + }; + + /* kernel-space interfaces */ + + /* + * for fbmem, highest 4-bits of address is fb index, + * rest of the bits are the offset + */ + struct { + __u32 ba; /* base address or index */ + __u32 uv; /* uv address */ + }; + }; +}; + +/* + * DSS2 manager information. + * + * The following information is deemed to be set globally, so it is not + * included: + * gamma correction + * whether to enable zorder (always enabled) + * whether to replicate/truncate color fields (it is decided per the + * whole manager/overlay settings, and is enabled unless overlay is + * directed to WB.) + * Notes: + * + * 1) trans_key_type and trans_enabled only need to be filled if + * trans_enabled is true, and alpha_blending is false. + */ +struct dss2_mgr_info { + __u32 ix; /* display index same as sysfs/display# */ + + __u32 default_color; + + enum omap_dss_trans_key_type trans_key_type; + __u32 trans_key; + struct omap_dss_cpr_coefs cpr_coefs; + + __u8 trans_enabled; /* bool */ + + __u8 interlaced; /* bool */ + __u8 alpha_blending; /* bool - overrides trans_enabled */ + __u8 cpr_enabled; /* bool */ + __u8 swap_rb; /* bool - swap red and blue */ +} __attribute__ ((aligned(4))); + +/* + * ioctl: DSSCIOC_SETUP_MGR, struct dsscomp_setup_mgr_data + * + * 1. sets manager of each ovl in composition to the display + * 2. calls set_dss_ovl_info() for each ovl to set up the + * overlay staging structures (this is a wrapper around ovl->set_info()) + * 3. calls set_dss_mgr_info() for mgr to set up the manager + * staging structures (this is a wrapper around mgr->set_info()) + * 4. if update is true: + * calls manager->apply() + * calls driver->update() in a non-blocking fashion + * this will program the DSS synchronously + * + * Notes: + * + * 1) x, y, w, h only needs to be set if update is true. + * + * All non-specified pipelines that currently are on the same display + * will remain the same as on the previous frame. You may want to + * disable unused pipelines to avoid surprises. + * + * If get_sync_obj is false, it returns 0 on success, <0 error value + * on failure. + * + * If get_sync_obj is true, it returns fd on success, or a negative value + * on failure. You can use the fd to wait on (using DSSCIOC_WAIT ioctl()). + * + * Note: frames do not get eclipsed when the display turns off. Queue a + * blank frame to eclipse old frames. Blank frames get eclipsed when + * programmed into DSS. + * + * (A blank frame is queued to the display automatically in Android before + * the display is turned off.) + * + * All overlays to be used on the frame must be listed. There is no way + * to add another overlay to a defined frame. + */ +enum dsscomp_setup_mode { + DSSCOMP_SETUP_MODE_APPLY = (1 << 0), /* applies changes to cache */ + DSSCOMP_SETUP_MODE_DISPLAY = (1 << 1), /* calls display update */ + DSSCOMP_SETUP_MODE_CAPTURE = (1 << 2), /* capture to WB */ + + /* just apply changes for next vsync/update */ + DSSCOMP_SETUP_APPLY = DSSCOMP_SETUP_MODE_APPLY, + /* trigger an update (wait for vsync) */ + DSSCOMP_SETUP_DISPLAY = + DSSCOMP_SETUP_MODE_APPLY | DSSCOMP_SETUP_MODE_DISPLAY, + /* capture to WB - WB must be configured */ + DSSCOMP_SETUP_CAPTURE = + DSSCOMP_SETUP_MODE_APPLY | DSSCOMP_SETUP_MODE_CAPTURE, + /* display and capture to WB - WB must be configured */ + DSSCOMP_SETUP_DISPLAY_CAPTURE = + DSSCOMP_SETUP_DISPLAY | DSSCOMP_SETUP_CAPTURE, +}; + +struct dsscomp_setup_mgr_data { + __u32 sync_id; /* synchronization ID - for debugging */ + + struct dss2_rect_t win; /* update region, set w/h to 0 for fullscreen */ + enum dsscomp_setup_mode mode; + __u16 num_ovls; /* # of overlays used in the composition */ + __u16 get_sync_obj; /* ioctl should return a sync object */ + + struct dss2_mgr_info mgr; + struct dss2_ovl_info ovls[0]; /* up to 5 overlays to set up */ +}; + +/* + * ioctl: DSSCIOC_CHECK_OVL, struct dsscomp_check_ovl_data + * + * DISPLAY and/or CAPTURE bits must be filled for the mode field + * correctly to be able to decide correctly if DSS can properly + * render the overlay. + * + * ovl.ix is ignored. + * + * Returns a positive bitmask regarding which overlay of DSS can + * render the overlay as it is configured for the display/display's + * manager. NOTE: that overlays that are assigned to other displays + * may be returned. If there is an invalid configuration (negative + * sizes, etc.), a negative error value is returned. + * + * ovl->decim's min values will be modified to the smallest decimation that + * DSS can use to support the overlay configuration. + * + * Assumptions: + * - zorder will be distinct from other pipelines on that manager + * - overlay will be enabled and routed to the display specified + */ +struct dsscomp_check_ovl_data { + enum dsscomp_setup_mode mode; + struct dss2_mgr_info mgr; + struct dss2_ovl_info ovl; +}; + +/* + * This structure is used to set up the entire DISPC (all managers), + * and is analogous to dsscomp_setup_mgr_data. + * + * Additional features: + * - all overlays that were specified in a prior use of this + * structure, and are no longer specified, will be disabled. + * - 1D buffers under 4M will be mapped into TILER1D. + * + * Limitations: + * - only DISPLAY mode is supported (DISPLAY and APPLY bits will + * automatically be set) + * - getting a sync object is not supported. + */ +struct dsscomp_setup_dispc_data { + __u32 sync_id; /* synchronization ID - for debugging */ + + enum dsscomp_setup_mode mode; + __u16 num_ovls; /* # of overlays used in the composition */ + __u16 num_mgrs; /* # of managers used in the composition */ + __u16 get_sync_obj; /* ioctl should return a sync object */ + + struct dss2_mgr_info mgrs[3]; + struct dss2_ovl_info ovls[5]; /* up to 5 overlays to set up */ +}; + +/* + * ioctl: DSSCIOC_WB_COPY, struct dsscomp_wb_copy_data + *, + * Requirements: + * wb.ix must be OMAP_DSS_WB. + * + * Returns 0 on success (copy is completed), non-0 on failure. + */ +struct dsscomp_wb_copy_data { + struct dss2_ovl_info ovl, wb; +}; + +/* + * ioctl: DSSCIOC_QUERY_DISPLAY, struct dsscomp_display_info + * + * Gets informations about the display. Fill in ix and modedb_len before + * calling ioctl, and rest of the fields are filled in by ioctl. Up to + * modedb_len timings are retrieved in the order of display preference. + * + * Returns: 0 on success, non-0 error value on failure. + */ +struct dsscomp_display_info { + __u32 ix; /* display index (sysfs/display#) */ + __u32 overlays_available; /* bitmask of available overlays */ + __u32 overlays_owned; /* bitmask of owned overlays */ + enum omap_channel channel; + enum omap_dss_display_state state; + __u8 enabled; /* bool: resume-state if suspended */ + struct omap_video_timings timings; + struct s3d_disp_info s3d_info; /* any S3D specific information */ + struct dss2_mgr_info mgr; /* manager information */ + __u16 width_in_mm; /* screen dimensions */ + __u16 height_in_mm; + + __u32 modedb_len; /* number of video timings */ + struct dsscomp_videomode modedb[]; /* display supported timings */ +}; + +/* + * ioctl: DSSCIOC_SETUP_DISPLAY, struct dsscomp_setup_display_data + * + * Gets informations about the display. Fill in ix before calling + * ioctl, and rest of the fields are filled in by ioctl. + * + * Returns: 0 on success, non-0 error value on failure. + */ +struct dsscomp_setup_display_data { + __u32 ix; /* display index (sysfs/display#) */ + struct dsscomp_videomode mode; /* video timings */ +}; + +/* + * ioctl: DSSCIOC_WAIT, struct dsscomp_wait_data + * + * Use this ioctl to wait for one of the following events: + * + * A) the moment a composition is programmed into DSS + * B) the moment a composition is first displayed (or captured) + * C) the moment when a composition is no longer queued or displayed on a + * display (it is released). (A composition is assumed to be superceded + * when another composition has been programmed into DSS, even if that + * subsequent composition does not update/specify all overlays used by + * the prior composition; moreover, even if it uses the same buffers.) + * + * Set timeout to desired timeout value in microseconds. + * + * This ioctl must be used on the sync object returned by the + * DSSCIOC_SETUP_MGR or DSSCIOC_SETUP_DISPC ioctls. + * + * Returns: >=0 on success, <0 error value on failure (e.g. -ETIME). + */ +enum dsscomp_wait_phase { + DSSCOMP_WAIT_PROGRAMMED = 1, + DSSCOMP_WAIT_DISPLAYED, + DSSCOMP_WAIT_RELEASED, +}; + +struct dsscomp_wait_data { + __u32 timeout_us; /* timeout in microseconds */ + enum dsscomp_wait_phase phase; /* phase to wait for */ +}; + +/* IOCTLS */ +#define DSSCIOC_SETUP_MGR _IOW('O', 128, struct dsscomp_setup_mgr_data) +#define DSSCIOC_CHECK_OVL _IOWR('O', 129, struct dsscomp_check_ovl_data) +#define DSSCIOC_WB_COPY _IOW('O', 130, struct dsscomp_wb_copy_data) +#define DSSCIOC_QUERY_DISPLAY _IOWR('O', 131, struct dsscomp_display_info) +#define DSSCIOC_WAIT _IOW('O', 132, struct dsscomp_wait_data) + +#define DSSCIOC_SETUP_DISPC _IOW('O', 133, struct dsscomp_setup_dispc_data) +#define DSSCIOC_SETUP_DISPLAY _IOW('O', 134, struct dsscomp_setup_display_data) +#endif diff --git a/include/video/hdmi_ti_4xxx_ip.h b/include/video/hdmi_ti_4xxx_ip.h new file mode 100644 index 0000000..49e7415 --- /dev/null +++ b/include/video/hdmi_ti_4xxx_ip.h @@ -0,0 +1,394 @@ +/* + * hdmi_ti_4xxx_ip.h + * + * HDMI driver definition for TI OMAP4 processors. + * + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * 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. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _HDMI_TI_4xxx_ +#define _HDMI_TI_4xxx_ + +#define HDMI_HPD_LOW 0x10 +#define HDMI_HPD_HIGH 0x20 +#define HDMI_BCAP 0x40 +#define HDMI_RI_ERR 0x80 +enum hdmi_pll_pwr { + HDMI_PLLPWRCMD_ALLOFF = 0, + HDMI_PLLPWRCMD_PLLONLY = 1, + HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2, + HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3 +}; + +enum hdmi_core_hdmi_dvi { + HDMI_DVI = 0, + HDMI_HDMI = 1 +}; + +enum hdmi_deep_color_mode { + HDMI_DEEP_COLOR_24BIT = 0, + HDMI_DEEP_COLOR_30BIT = 1, + HDMI_DEEP_COLOR_36BIT = 2 +}; + +struct hdmi_ip_data { + void __iomem *base_wp; /* HDMI wrapper */ + unsigned long hdmi_core_sys_offset; + unsigned long hdmi_core_av_offset; + unsigned long hdmi_pll_offset; + unsigned long hdmi_phy_offset; +}; + +struct hdmi_video_timings { + u16 x_res; + u16 y_res; + /* Unit: KHz */ + u32 pixel_clock; + u16 hsw; + u16 hfp; + u16 hbp; + u16 vsw; + u16 vfp; + u16 vbp; +}; + +/* HDMI timing structure */ +struct hdmi_timings { + struct hdmi_video_timings timings; + int vsync_pol; + int hsync_pol; +}; + +struct hdmi_cm { + int code; + int mode; +}; + +struct hdmi_config { + struct fb_videomode timings; + struct hdmi_cm cm; + enum hdmi_deep_color_mode deep_color; +}; + +/* HDMI PLL structure */ +struct hdmi_pll_info { + u16 regn; + u16 regm; + u32 regmf; + u16 regm2; + u16 regsd; + u16 dcofreq; +}; + +struct hdmi_core_audio_i2s_config { + u8 word_max_length; + u8 word_length; + u8 in_length_bits; + u8 justification; + u8 en_high_bitrate_aud; + u8 sck_edge_mode; + u8 cbit_order; + u8 vbit; + u8 ws_polarity; + u8 direction; + u8 shift; + u8 active_sds; +}; + + +enum hdmi_audio_i2s_config { + HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT = 0, + HDMI_AUDIO_I2S_WS_POLARIT_YLOW_IS_RIGHT = 1, + HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0, + HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1, + HDMI_AUDIO_I2S_MAX_WORD_20BITS = 0, + HDMI_AUDIO_I2S_MAX_WORD_24BITS = 1, + HDMI_AUDIO_I2S_CHST_WORD_NOT_SPECIFIED = 0, + HDMI_AUDIO_I2S_CHST_WORD_16_BITS = 1, + HDMI_AUDIO_I2S_CHST_WORD_17_BITS = 6, + HDMI_AUDIO_I2S_CHST_WORD_18_BITS = 2, + HDMI_AUDIO_I2S_CHST_WORD_19_BITS = 4, + HDMI_AUDIO_I2S_CHST_WORD_20_BITS_20MAX = 5, + HDMI_AUDIO_I2S_CHST_WORD_20_BITS_24MAX = 1, + HDMI_AUDIO_I2S_CHST_WORD_21_BITS = 6, + HDMI_AUDIO_I2S_CHST_WORD_22_BITS = 2, + HDMI_AUDIO_I2S_CHST_WORD_23_BITS = 4, + HDMI_AUDIO_I2S_CHST_WORD_24_BITS = 5, + HDMI_AUDIO_I2S_SCK_EDGE_FALLING = 0, + HDMI_AUDIO_I2S_SCK_EDGE_RISING = 1, + HDMI_AUDIO_I2S_VBIT_FOR_PCM = 0, + HDMI_AUDIO_I2S_VBIT_FOR_COMPRESSED = 1, + HDMI_AUDIO_I2S_INPUT_LENGTH_NA = 0, + HDMI_AUDIO_I2S_INPUT_LENGTH_16 = 2, + HDMI_AUDIO_I2S_INPUT_LENGTH_17 = 12, + HDMI_AUDIO_I2S_INPUT_LENGTH_18 = 4, + HDMI_AUDIO_I2S_INPUT_LENGTH_19 = 8, + HDMI_AUDIO_I2S_INPUT_LENGTH_20 = 10, + HDMI_AUDIO_I2S_INPUT_LENGTH_21 = 13, + HDMI_AUDIO_I2S_INPUT_LENGTH_22 = 5, + HDMI_AUDIO_I2S_INPUT_LENGTH_23 = 9, + HDMI_AUDIO_I2S_INPUT_LENGTH_24 = 11, + HDMI_AUDIO_I2S_FIRST_BIT_SHIFT = 0, + HDMI_AUDIO_I2S_FIRST_BIT_NO_SHIFT = 1, + HDMI_AUDIO_I2S_SD0_EN = 1, + HDMI_AUDIO_I2S_SD1_EN = 1 << 1, + HDMI_AUDIO_I2S_SD2_EN = 1 << 2, + HDMI_AUDIO_I2S_SD3_EN = 1 << 3, +}; + +enum hdmi_audio_mclk_mode { + HDMI_AUDIO_MCLK_128FS = 0, + HDMI_AUDIO_MCLK_256FS = 1, + HDMI_AUDIO_MCLK_384FS = 2, + HDMI_AUDIO_MCLK_512FS = 3, + HDMI_AUDIO_MCLK_768FS = 4, + HDMI_AUDIO_MCLK_1024FS = 5, + HDMI_AUDIO_MCLK_1152FS = 6, + HDMI_AUDIO_MCLK_192FS = 7 +}; + + +enum hdmi_core_audio_sample_freq { + HDMI_AUDIO_FS_32000 = 0x3, + HDMI_AUDIO_FS_44100 = 0x0, + HDMI_AUDIO_FS_48000 = 0x2, + HDMI_AUDIO_FS_88200 = 0x8, + HDMI_AUDIO_FS_96000 = 0xA, + HDMI_AUDIO_FS_176400 = 0xC, + HDMI_AUDIO_FS_192000 = 0xE, + HDMI_AUDIO_FS_NOT_INDICATED = 0x1 +}; + +enum hdmi_core_audio_layout { + HDMI_AUDIO_LAYOUT_2CH = 0, + HDMI_AUDIO_LAYOUT_8CH = 1 +}; + +enum hdmi_core_cts_mode { + HDMI_AUDIO_CTS_MODE_HW = 0, + HDMI_AUDIO_CTS_MODE_SW = 1 +}; + +enum hdmi_stereo_channels { + HDMI_AUDIO_STEREO_NOCHANNELS = 0, + HDMI_AUDIO_STEREO_ONECHANNEL = 1, + HDMI_AUDIO_STEREO_TWOCHANNELS = 2, + HDMI_AUDIO_STEREO_THREECHANNELS = 3, + HDMI_AUDIO_STEREO_FOURCHANNELS = 4 +}; + +enum hdmi_audio_type { + HDMI_AUDIO_TYPE_LPCM = 0, + HDMI_AUDIO_TYPE_IEC = 1 +}; + +enum hdmi_audio_justify { + HDMI_AUDIO_JUSTIFY_LEFT = 0, + HDMI_AUDIO_JUSTIFY_RIGHT = 1 +}; + +enum hdmi_audio_sample_order { + HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0, + HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1 +}; + +enum hdmi_audio_samples_perword { + HDMI_AUDIO_ONEWORD_ONESAMPLE = 0, + HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1 +}; + +enum hdmi_audio_sample_size { + HDMI_AUDIO_SAMPLE_16BITS = 0, + HDMI_AUDIO_SAMPLE_24BITS = 1 +}; + +enum hdmi_audio_transf_mode { + HDMI_AUDIO_TRANSF_DMA = 0, + HDMI_AUDIO_TRANSF_IRQ = 1 +}; + +enum hdmi_audio_blk_strt_end_sig { + HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0, + HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1 +}; + + +struct hdmi_core_audio_config { + struct hdmi_core_audio_i2s_config i2s_cfg; + enum hdmi_core_audio_sample_freq freq_sample; + bool fs_override; + u32 n; + u32 cts; + u32 aud_par_busclk; + enum hdmi_core_audio_layout layout; + enum hdmi_core_cts_mode cts_mode; + bool use_mclk; + enum hdmi_audio_mclk_mode mclk_mode; + bool en_acr_pkt; + bool en_dsd_audio; + bool en_parallel_aud_input; + bool en_spdif; +}; + + + +struct hdmi_audio_format { + enum hdmi_stereo_channels stereo_channels; + u8 active_chnnls_msk; + enum hdmi_audio_type type; + enum hdmi_audio_justify justification; + enum hdmi_audio_sample_order sample_order; + enum hdmi_audio_samples_perword samples_per_word; + enum hdmi_audio_sample_size sample_size; + enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end; +}; + +struct hdmi_audio_dma { + u8 transfer_size; + u8 block_size; + enum hdmi_audio_transf_mode mode; + u16 fifo_threshold; +}; + +/* + * Refer to section 8.2 in HDMI 1.3 specification for + * details about infoframe databytes + */ +struct hdmi_core_infoframe_audio { + u8 db1_coding_type; + u8 db1_channel_count; + u8 db2_sample_freq; + u8 db2_sample_size; + u8 db4_channel_alloc; + bool db5_downmix_inh; + u8 db5_lsv; /* Level shift values for downmix */ +}; + + + +/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */ +enum hdmi_core_infoframe { + HDMI_INFOFRAME_AVI_DB1Y_RGB = 0, + HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1, + HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2, + HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0, + HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1, + HDMI_INFOFRAME_AVI_DB1B_NO = 0, + HDMI_INFOFRAME_AVI_DB1B_VERT = 1, + HDMI_INFOFRAME_AVI_DB1B_HORI = 2, + HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3, + HDMI_INFOFRAME_AVI_DB1S_0 = 0, + HDMI_INFOFRAME_AVI_DB1S_1 = 1, + HDMI_INFOFRAME_AVI_DB1S_2 = 2, + HDMI_INFOFRAME_AVI_DB2C_NO = 0, + HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1, + HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2, + HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3, + HDMI_INFOFRAME_AVI_DB2M_NO = 0, + HDMI_INFOFRAME_AVI_DB2M_43 = 1, + HDMI_INFOFRAME_AVI_DB2M_169 = 2, + HDMI_INFOFRAME_AVI_DB2R_SAME = 8, + HDMI_INFOFRAME_AVI_DB2R_43 = 9, + HDMI_INFOFRAME_AVI_DB2R_169 = 10, + HDMI_INFOFRAME_AVI_DB2R_149 = 11, + HDMI_INFOFRAME_AVI_DB3ITC_NO = 0, + HDMI_INFOFRAME_AVI_DB3ITC_YES = 1, + HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0, + HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1, + HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0, + HDMI_INFOFRAME_AVI_DB3Q_LR = 1, + HDMI_INFOFRAME_AVI_DB3Q_FR = 2, + HDMI_INFOFRAME_AVI_DB3SC_NO = 0, + HDMI_INFOFRAME_AVI_DB3SC_HORI = 1, + HDMI_INFOFRAME_AVI_DB3SC_VERT = 2, + HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3, + HDMI_INFOFRAME_AVI_DB5PR_NO = 0, + HDMI_INFOFRAME_AVI_DB5PR_2 = 1, + HDMI_INFOFRAME_AVI_DB5PR_3 = 2, + HDMI_INFOFRAME_AVI_DB5PR_4 = 3, + HDMI_INFOFRAME_AVI_DB5PR_5 = 4, + HDMI_INFOFRAME_AVI_DB5PR_6 = 5, + HDMI_INFOFRAME_AVI_DB5PR_7 = 6, + HDMI_INFOFRAME_AVI_DB5PR_8 = 7, + HDMI_INFOFRAME_AVI_DB5PR_9 = 8, + HDMI_INFOFRAME_AVI_DB5PR_10 = 9, + HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM = 0, + HDMI_INFOFRAME_AUDIO_DB1CT_IEC60958 = 1, + HDMI_INFOFRAME_AUDIO_DB1CT_AC3 = 2, + HDMI_INFOFRAME_AUDIO_DB1CT_MPEG1 = 3, + HDMI_INFOFRAME_AUDIO_DB1CT_MP3 = 4, + HDMI_INFOFRAME_AUDIO_DB1CT_MPEG2_MULTICH = 5, + HDMI_INFOFRAME_AUDIO_DB1CT_AAC = 6, + HDMI_INFOFRAME_AUDIO_DB1CT_DTS = 7, + HDMI_INFOFRAME_AUDIO_DB1CT_ATRAC = 8, + HDMI_INFOFRAME_AUDIO_DB1CT_ONEBIT = 9, + HDMI_INFOFRAME_AUDIO_DB1CT_DOLBY_DIGITAL_PLUS = 10, + HDMI_INFOFRAME_AUDIO_DB1CT_DTS_HD = 11, + HDMI_INFOFRAME_AUDIO_DB1CT_MAT = 12, + HDMI_INFOFRAME_AUDIO_DB1CT_DST = 13, + HDMI_INFOFRAME_AUDIO_DB1CT_WMA_PRO = 14, + HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM = 0, + HDMI_INFOFRAME_AUDIO_DB2SF_32000 = 1, + HDMI_INFOFRAME_AUDIO_DB2SF_44100 = 2, + HDMI_INFOFRAME_AUDIO_DB2SF_48000 = 3, + HDMI_INFOFRAME_AUDIO_DB2SF_88200 = 4, + HDMI_INFOFRAME_AUDIO_DB2SF_96000 = 5, + HDMI_INFOFRAME_AUDIO_DB2SF_176400 = 6, + HDMI_INFOFRAME_AUDIO_DB2SF_192000 = 7, + HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM = 0, + HDMI_INFOFRAME_AUDIO_DB2SS_16BIT = 1, + HDMI_INFOFRAME_AUDIO_DB2SS_20BIT = 2, + HDMI_INFOFRAME_AUDIO_DB2SS_24BIT = 3, + HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PERMITTED = 0, + HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PROHIBITED = 1 +}; + +enum hdmi_aksv_err { + HDMI_AKSV_ZERO = 0, + HDMI_AKSV_ERROR = 1, + HDMI_AKSV_VALID = 2 +}; + +int hdmi_ti_4xxx_phy_init(struct hdmi_ip_data *ip_data); +void hdmi_ti_4xxx_phy_off(struct hdmi_ip_data *ip_data, bool set_mode); +int read_ti_4xxx_edid(struct hdmi_ip_data *ip_data, u8 *pedid, u16 max_length); +void hdmi_ti_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start); +int hdmi_ti_4xxx_pll_program(struct hdmi_ip_data *ip_data, + struct hdmi_pll_info *fmt); +int hdmi_ti_4xxx_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val); +void hdmi_ti_4xxx_basic_configure(struct hdmi_ip_data *ip_data, + struct hdmi_config *cfg); +int hdmi_ti_4xxx_rxdet(struct hdmi_ip_data *ip_data); +int hdmi_ti_4xxx_wp_get_video_state(struct hdmi_ip_data *ip_data); +u32 hdmi_ti_4xxx_irq_handler(struct hdmi_ip_data *ip_data); +void hdmi_ti_4xxx_dump_regs(struct hdmi_ip_data *ip_data, struct seq_file *s); +int hdmi_ti_4xxx_config_audio_acr(struct hdmi_ip_data *ip_data, + u32 sample_freq, u32 *n, u32 *cts, u32 pclk); +void hdmi_ti_4xxx_wp_audio_config_dma(struct hdmi_ip_data *ip_data, + struct hdmi_audio_dma *aud_dma); + +void hdmi_ti_4xxx_wp_audio_config_format(struct hdmi_ip_data *ip_data, + struct hdmi_audio_format *aud_fmt); +void hdmi_ti_4xxx_core_audio_config(struct hdmi_ip_data *ip_data, + struct hdmi_core_audio_config *cfg); +void hdmi_ti_4xxx_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, + struct hdmi_core_infoframe_audio *info_aud); +void hdmi_ti_4xxx_audio_transfer_en(struct hdmi_ip_data *ip_data, + bool idle); +void hdmi_ti_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool idle); + +int hdmi_ti_4xxx_set_wait_soft_reset(struct hdmi_ip_data *ip_data); +int hdmi_ti_4xx_check_aksv_data(struct hdmi_ip_data *ip_data); +#endif diff --git a/include/video/omapdss.h b/include/video/omapdss.h index c0d8014..3be0bc3 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -21,8 +21,7 @@ #include <linux/list.h> #include <linux/kobject.h> #include <linux/device.h> -#include <linux/platform_device.h> -#include <asm/atomic.h> +#include <linux/fb.h> #define DISPC_IRQ_FRAMEDONE (1 << 0) #define DISPC_IRQ_VSYNC (1 << 1) @@ -43,8 +42,11 @@ #define DISPC_IRQ_WAKEUP (1 << 16) #define DISPC_IRQ_SYNC_LOST2 (1 << 17) #define DISPC_IRQ_VSYNC2 (1 << 18) +#define DISPC_IRQ_VID3_END_WIN (1 << 19) +#define DISPC_IRQ_VID3_FIFO_UNDERFLOW (1 << 20) #define DISPC_IRQ_ACBIAS_COUNT_STAT2 (1 << 21) #define DISPC_IRQ_FRAMEDONE2 (1 << 22) +#define DISPC_IRQ_FRAMEDONETV (1 << 24) struct omap_dss_device; struct omap_overlay_manager; @@ -62,7 +64,8 @@ enum omap_display_type { enum omap_plane { OMAP_DSS_GFX = 0, OMAP_DSS_VIDEO1 = 1, - OMAP_DSS_VIDEO2 = 2 + OMAP_DSS_VIDEO2 = 2, + OMAP_DSS_VIDEO3 = 3, }; enum omap_channel { @@ -126,6 +129,11 @@ enum omap_panel_config { OMAP_DSS_LCD_TFT = 1<<20, }; +enum omap_dss_dsi_type { + OMAP_DSS_DSI_TYPE_CMD_MODE = 0, + OMAP_DSS_DSI_TYPE_VIDEO_MODE, +}; + enum omap_dss_venc_type { OMAP_DSS_VENC_TYPE_COMPOSITE, OMAP_DSS_VENC_TYPE_SVIDEO, @@ -148,6 +156,11 @@ enum omap_dss_display_state { OMAP_DSS_DISPLAY_SUSPENDED, }; +enum omap_dispc_irq_type { + OMAP_DISPC_IRQ_TYPE_FRAMEDONE, + OMAP_DISPC_IRQ_TYPE_VSYNC, +}; + /* XXX perhaps this should be removed */ enum omap_dss_overlay_managers { OMAP_DSS_OVL_MGR_LCD, @@ -158,6 +171,7 @@ enum omap_dss_overlay_managers { enum omap_dss_rotation_type { OMAP_DSS_ROT_DMA = 0, OMAP_DSS_ROT_VRFB = 1, + OMAP_DSS_ROT_TILER = 2, }; /* clockwise rotation angle */ @@ -188,6 +202,13 @@ enum omap_dss_clk_source { OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI, /* OMAP4: PLL2_CLK2 */ }; +enum omap_overlay_zorder { + OMAP_DSS_OVL_ZORDER_0 = 0, + OMAP_DSS_OVL_ZORDER_1 = 1, + OMAP_DSS_OVL_ZORDER_2 = 2, + OMAP_DSS_OVL_ZORDER_3 = 3, +}; + /* RFBI */ struct rfbi_timings { @@ -244,9 +265,11 @@ int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel, int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel); int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel); +int dsi_video_mode_enable(struct omap_dss_device *dssdev, u8 data_type); + /* Board specific data */ struct omap_dss_board_info { - int (*get_last_off_on_transaction_id)(struct device *dev); + int (*get_context_loss_count)(struct device *dev); int num_devices; struct omap_dss_device **devices; struct omap_dss_device *default_device; @@ -266,8 +289,6 @@ static inline int omap_display_init(struct omap_dss_board_info *board_data) struct omap_display_platform_data { struct omap_dss_board_info *board_data; /* TODO: Additional members to be added when PM is considered */ - - bool (*opt_clock_available)(const char *clk_role); }; struct omap_video_timings { @@ -300,6 +321,41 @@ extern const struct omap_video_timings omap_dss_pal_timings; extern const struct omap_video_timings omap_dss_ntsc_timings; #endif +enum omapdss_completion_status { + DSS_COMPLETION_PROGRAMMED = (1 << 1), + DSS_COMPLETION_DISPLAYED = (1 << 2), + + DSS_COMPLETION_CHANGED_SET = (1 << 3), + DSS_COMPLETION_CHANGED_CACHE = (1 << 4), + DSS_COMPLETION_CHANGED = (3 << 3), + + DSS_COMPLETION_RELEASED = (15 << 5), + DSS_COMPLETION_ECLIPSED_SET = (1 << 5), + DSS_COMPLETION_ECLIPSED_CACHE = (1 << 6), + DSS_COMPLETION_ECLIPSED_SHADOW = (1 << 7), + DSS_COMPLETION_TORN = (1 << 8), +}; + +struct omapdss_ovl_cb { + /* optional callback method */ + u32 (*fn)(void *data, int id, int status); + void *data; + u32 mask; +}; + +struct omap_dss_cpr_coefs { + s16 rr, rg, rb; + s16 gr, gg, gb; + s16 br, bg, bb; +}; + +struct omap_dss_cconv_coefs { + s16 ry, rcr, rcb; + s16 gy, gcr, gcb; + s16 by, bcr, bcb; + u16 full_range; +} __attribute__ ((aligned(4))); + struct omap_overlay_info { bool enabled; @@ -320,6 +376,11 @@ struct omap_overlay_info { u16 out_height; /* if 0, out_height == height */ u8 global_alpha; u8 pre_mult_alpha; + enum omap_overlay_zorder zorder; + u16 min_x_decim, max_x_decim, min_y_decim, max_y_decim; + struct omap_dss_cconv_coefs cconv; + + struct omapdss_ovl_cb cb; }; struct omap_overlay { @@ -359,6 +420,11 @@ struct omap_overlay_manager_info { bool trans_enabled; bool alpha_enabled; + + struct omapdss_ovl_cb cb; + + bool cpr_enable; + struct omap_dss_cpr_coefs cpr_coefs; }; struct omap_overlay_manager { @@ -393,6 +459,8 @@ struct omap_overlay_manager { int (*apply)(struct omap_overlay_manager *mgr); int (*wait_for_go)(struct omap_overlay_manager *mgr); int (*wait_for_vsync)(struct omap_overlay_manager *mgr); + int (*blank)(struct omap_overlay_manager *mgr, bool wait_for_vsync); + void (*dump_cb)(struct omap_overlay_manager *mgr, struct seq_file *s); int (*enable)(struct omap_overlay_manager *mgr); int (*disable)(struct omap_overlay_manager *mgr); @@ -405,6 +473,9 @@ struct omap_dss_device { enum omap_channel channel; + bool first_vsync; + bool sync_lost_error; + union { struct { u8 data_lines; @@ -420,6 +491,7 @@ struct omap_dss_device { } sdi; struct { + enum omap_dss_dsi_type type; u8 clk_lane; u8 clk_pol; u8 data1_lane; @@ -430,7 +502,6 @@ struct omap_dss_device { u8 data3_pol; u8 data4_lane; u8 data4_pol; - int module; bool ext_te; @@ -461,12 +532,15 @@ struct omap_dss_device { u16 regm_dsi; u16 lp_clk_div; + unsigned offset_ddr_clk; enum omap_dss_clk_source dsi_fclk_src; } dsi; struct { u16 regn; u16 regm2; + + u32 max_pixclk_khz; } hdmi; } clocks; @@ -478,6 +552,10 @@ struct omap_dss_device { int acb; /* ac-bias pin frequency */ enum omap_panel_config config; + struct fb_monspecs monspecs; + + u32 width_in_um; + u32 height_in_um; } panel; struct { @@ -486,6 +564,9 @@ struct omap_dss_device { } ctrl; int reset_gpio; + int hpd_gpio; + + bool skip_init; int max_backlight_level; @@ -507,6 +588,8 @@ struct omap_dss_device { enum omap_dss_display_state state; + struct blocking_notifier_head state_notifiers; + /* platform specific */ int (*platform_enable)(struct omap_dss_device *dssdev); void (*platform_disable)(struct omap_dss_device *dssdev); @@ -568,6 +651,15 @@ struct omap_dss_driver { int (*set_wss)(struct omap_dss_device *dssdev, u32 wss); u32 (*get_wss)(struct omap_dss_device *dssdev); + int (*get_modedb)(struct omap_dss_device *dssdev, + struct fb_videomode *modedb, + int modedb_len); + int (*set_mode)(struct omap_dss_device *dssdev, + struct fb_videomode *mode); + + /* for wrapping around state changes */ + void (*disable_orig)(struct omap_dss_device *display); + int (*enable_orig)(struct omap_dss_device *display); }; int omap_dss_register_driver(struct omap_dss_driver *); @@ -601,9 +693,14 @@ int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout); int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask, unsigned long timeout); +void omap_dispc_set_irq_type(int channel, enum omap_dispc_irq_type type); + #define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver) #define to_dss_device(x) container_of((x), struct omap_dss_device, dev) +void omapdss_display_get_dimensions(struct omap_dss_device *dssdev, + u32 *width_in_um, u32 *height_in_um); + void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, bool enable); int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable); @@ -643,4 +740,18 @@ int omap_rfbi_update(struct omap_dss_device *dssdev, int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size, int data_lines); +int omap_dss_manager_unregister_callback(struct omap_overlay_manager *mgr, + struct omapdss_ovl_cb *cb); + +/* generic callback handling */ +static inline void dss_ovl_cb(struct omapdss_ovl_cb *cb, int id, int status) +{ + if (cb->fn && (cb->mask & status)) + cb->mask &= cb->fn(cb->data, id, status); + if (status & DSS_COMPLETION_RELEASED) + cb->mask = 0; + if (!cb->mask) + cb->fn = NULL; +} + #endif |