Initial Contribution

msm-2.6.38: tag AU_LINUX_ANDROID_GINGERBREAD.02.03.04.00.142

Signed-off-by: Bryan Huntsman <bryanh@codeaurora.org>
diff --git a/Documentation/arm/msm/boot.txt b/Documentation/arm/msm/boot.txt
new file mode 100644
index 0000000..1a41cd5
--- /dev/null
+++ b/Documentation/arm/msm/boot.txt
@@ -0,0 +1,23 @@
+Introduction
+=============
+The power management integrated circuit (PMIC) records the reason the
+Application processor was powered on in Shared Memory.
+The hardware and software used is the shared memory interface. This document
+is not for the purpose of describing this interface, but to identify the
+possible values for this data item.
+
+Description
+===========
+Shared memory item (SMEM_POWER_ON_STATUS_INFO) is read to get access to
+this data. The table below identifies the possible values stored.
+
+power_on_status values set by the PMIC for power on event:
+----------------------------------------------------------
+0x01 -- keyboard power on
+0x02 -- RTC alarm
+0x04 -- cable power on
+0x08 -- SMPL
+0x10 -- Watch Dog timeout
+0x20 -- USB charger
+0x40 -- Wall charger
+0xFF -- error reading power_on_status value
diff --git a/Documentation/arm/msm/emulate_domain_manager.txt b/Documentation/arm/msm/emulate_domain_manager.txt
new file mode 100644
index 0000000..b0d007e
--- /dev/null
+++ b/Documentation/arm/msm/emulate_domain_manager.txt
@@ -0,0 +1,254 @@
+Introduction
+============
+
+8x50 chipset requires the ability to disable HW domain manager function.
+
+The ARM MMU architecture has a feature known as domain manager mode.
+Briefly each page table, section, or supersection is assigned a domain.
+Each domain can be globally configured to NoAccess, Client, or Manager
+mode.  These global configurations allow the access permissions of the
+entire domain to be changed simultaneously.
+
+The domain manger emulation is required to fix a HW problem on the 8x50
+chipset.  The problem is simple to repair except when domain manager mode
+is enabled.  The emulation allows the problem to be completely resolved.
+
+
+Hardware description
+====================
+
+When domain manager mode is enabled on a specific domain, the MMU
+hardware ignores the access permission bits and the execute never bit.  All
+accesses, to memory in the domain, are granted full read, write,
+execute permissions.
+
+The mode of each domain is controlled by a field in the cp15 dacr register.
+Each domain can be globally configured to NoAccess, Client, or Manager mode.
+
+See: ARMv7 Architecture Reference Manual
+
+
+Software description
+====================
+
+In order to disable domain manager mode the equivalent HW functionality must
+be emulated in SW.  Any attempts to enable domain manager mode, must be
+intercepted.
+
+Because domain manager mode is not enabled, permissions for the
+associated domain will remain restricted.  Permission faults will be generated.
+The permission faults will be intercepted.  The faulted pages/sections will
+be modified to grant full access and execute permissions.
+
+The modified page tables must be restored when exiting domain manager mode.
+
+
+Design
+======
+
+Design Goals:
+
+Disable Domain Manager Mode
+Exact SW emulation of Domain Manager Mode
+Minimal Kernel changes
+Minimal Security Risk
+
+Design Decisions:
+
+Detect kernel page table modifications on restore
+Direct ARMv7 HW MMU table manipulation
+Restore emulation modified MMU entries on context switch
+No need to restore MMU entries for MMU entry copy operations
+Invalidate TLB entries on modification
+Store Domain Manager bits in memory
+8 entry MMU entry cache
+Use spin_lock_irqsave to protect domain manipulation
+Assume no split MMU table
+
+Design Discussion:
+
+Detect kernel page table modifications on restore -
+When restoring original page/section permission faults, the submitted design
+verifies the MMU entry has not been modified.  The kernel modifies MMU
+entries for the following purposes : create a memory mapping, release a
+memory mapping, add permissions during a permission fault, and map a page
+during a translation fault.  The submitted design works with the listed
+scenarios.  The translation fault and permission faults simply do not happen on
+relevant entries (valid entries with full access permissions).  The alternative
+would be to hook every MMU table modification.  The alternative greatly
+increases complexity and code maintenance issues.
+
+Direct ARMv7 HW MMU table manipulation -
+The natural choice would be to use the kernel provided mechanism to manipulate
+MMU page table entries.  The ARM MMU interface is described in pgtable.h.
+This interface is complicated by the Linux implementation.  The level 1 pgd
+entries are treated and manipulated as entry pairs.  The level 2 entries are
+shadowed and cloned.  The compromise was chosen to actually use the ARMv7 HW
+registers to walk and modify the MMU table entries.  The choice limits the
+usage of this implementation to ARMv7 and similar ARM MMU architectures.  Since
+this implementation is targeted at fixing an issue in 8x50 ARMv7, the choice is
+logical.  The HW manipulation is in distinct low level functions.  These could
+easily be replaced or generalized to support other architectures as necessary.
+
+Restore emulation modified MMU entries on context switch -
+This additional hook was added to minimize performance impact.  By guaranteeing
+the ASID will not change during the emulation, the emulation may invalidate each
+entry by MVA & ASID.  Only the affected page table entries will be removed from
+the TLB cache.  The performance cost of the invalidate on context switch is near
+zero.  Typically on context switch the domain mode would also change, forcing a
+complete restore of all modified MMU entries.  The alternative would be to
+invalidate the entire TLB every time a table entry is restored.
+
+No need to restore MMU entries for copy operations -
+Operations which copy MMU entries are relatively rare in the kernel.  Because
+we modify the level 2 pte entries directly in hardware, the Linux shadow copies
+are left untouched.  The kernel treats the shadow copies as the primary pte
+entry.  Any pte copy operations would be unaffected by the HW modification.
+On translation section fault, pgd entries are copied from the kernel master
+page table to the current thread page table.  Since we restore MMU entries on
+context switch, we guarantee the master table will not contain modifications,
+while faulting on a process local entry.  Other read, modify write operations
+occur during permission fault handling.  Since we open permission on modified
+entries, these do not need to be restored, because we guarantee these
+permission fault operations will not happen.
+
+Invalidate TLB entries on modification -
+No real choice here.  This is more of a design requirement.  On permission
+fault, the MMU entry with restricted permissions will be in the TLB.  To open
+access permissions, the TLB entry must be invalidated.  Otherwise the access
+will permission fault again.  Upon restoring original MMU entries, the TLB
+must be invalidated to restrict memory access.
+
+Store Domain Manager bits in memory -
+There was only one alternative here.  2.6.29 kernel only uses 3 of 16
+possible domains.  Additional bits in dacr could be used to store the
+manager bits.  This would allow faster access to the manager bits.
+Overall this would reduce any performance impact.  The performance
+needs did not seem to justify the added weirdness.
+
+8 entry MMU entry cache-
+The size of the modified MMU entry cache is somewhat arbitrary.  The thought
+process is that typically, a thread is using two pointers to perform a copy
+operation.  In this case only 2 entries would be required.  One could imagine
+a more complicated operation, a masked copy for instance, which would require
+more pointers.  8 pointer seemed to be large enough to minimize risk of
+permission fault thrashing.  The disadvantage of a larger cache would simply
+be a longer list of entries to restore.
+
+Use spin_lock_irqsave to protect domain manipulation -
+The obvious choice.
+
+Assume no split MMU table -
+This same assumption is documented in cpu_v7_switch_mm.
+
+
+Power Management
+================
+
+Not affected.
+
+
+SMP/multi-core
+==============
+
+SMP/multicore not supported.  This is intended as a 8x50 workaround.
+
+
+Security
+========
+
+MMU page/section permissions must be manipulated correctly to emulate domain
+manager mode.  If page permission are left in full access mode, any process
+can read associated memory.
+
+
+Performance
+===========
+
+Performance should be impacted only minimally.  When emulating domain manager
+mode, there is overhead added to MMU table/context switches, set_domain()
+calls, data aborts, and prefetch aborts.
+
+Normally the kernel operates with domain != DOMAIN_MANAGER.  In this case the
+overhead is minimal.  An additional check is required to see if domain manager
+mode is on.  This minimal code is added to each of emulation entry points :
+set, data abort, prefetch abort, and MMU table/context switch.
+
+Initial accesses to a MMU protected page/section will generate a permission
+fault. The page will be manipulated to grant full access permissions and
+the access will be retried.  This will typically require 2-3 page table
+walks.
+
+On a context switch, all modified MMU entries will be restored.  On thread
+resume, additional accesses will be treated as initial accesses.
+
+
+Interface
+=========
+
+The emulation does not have clients.  It is hooked to the kernel through a
+small list of functions.
+
+void emulate_domain_manager_set(u32 domain);
+int emulate_domain_manager_data_abort(u32 dfsr, u32 dfar);
+int emulate_domain_manager_prefetch_abort(u32 ifsr, u32 ifar);
+void emulate_domain_manager_switch_mm(
+	unsigned long pgd_phys,
+	struct mm_struct *mm,
+	void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *));
+
+emulate_domain_manager_set() is the set_domain handler.  This replaces the
+direct manipulation of CP15 dacr with a function call.  This allows emulation
+to prevent setting dacr manager bits.  It also allows emulation to restore
+page/section permissions when domain manger is disabled.
+
+emulate_domain_manager_data_abort() handles data aborts caused by domain
+not being set in HW, and handles section/page manipulation.
+
+emulate_domain_manager_prefetch_abort() is the similar prefetch abort handler.
+
+emulate_domain_manager_switch_mm() handles MMU table and context switches.
+This notifies the emulation that the MMU context is changing.  Allowing the
+emulation to restore page table entry permission before switching contexts.
+
+
+Config options
+==============
+
+This option is enable/disable by the EMULATE_DOMAIN_MANAGER_V7 option.
+
+
+Dependencies
+============
+
+Implementation is for ARMv7, MMU, and !SMP.  Targets solving issue for 8x50
+chipset.
+
+
+User space utilities
+====================
+
+None
+
+
+Other
+=====
+
+Code is implemented in kernel/arch/arm/mm.
+
+
+arch/arm/mm/emulate_domain_manager.c contains comments.  No additional public
+documentation available or planned.
+
+
+Known issues
+============
+
+No intent to support SMP or non ARMv7 architectures
+
+
+To do
+=====
+
+None
+
diff --git a/Documentation/arm/msm/gpiomux.txt b/Documentation/arm/msm/gpiomux.txt
index 67a8162..aaf0793 100644
--- a/Documentation/arm/msm/gpiomux.txt
+++ b/Documentation/arm/msm/gpiomux.txt
@@ -2,112 +2,79 @@
 is used to provide gpio pin multiplexing and configuration on mach-msm
 targets.
 
-History
-=======
-
-The first-generation API for gpio configuration & multiplexing on msm
-is the function gpio_tlmm_config().  This function has a few notable
-shortcomings, which led to its deprecation and replacement by gpiomux:
-
-The 'disable' parameter:  Setting the second parameter to
-gpio_tlmm_config to GPIO_CFG_DISABLE tells the peripheral
-processor in charge of the subsystem to perform a look-up into a
-low-power table and apply the low-power/sleep setting for the pin.
-As the msm family evolved this became problematic. Not all pins
-have sleep settings, not all peripheral processors will accept requests
-to apply said sleep settings, and not all msm targets have their gpio
-subsystems managed by a peripheral processor. In order to get consistent
-behavior on all targets, drivers are forced to ignore this parameter,
-rendering it useless.
-
-The 'direction' flag: for all mux-settings other than raw-gpio (0),
-the output-enable bit of a gpio is hard-wired to a known
-input (usually VDD or ground).  For those settings, the direction flag
-is meaningless at best, and deceptive at worst.  In addition, using the
-direction flag to change output-enable (OE) directly can cause trouble in
-gpiolib, which has no visibility into gpio direction changes made
-in this way.  Direction control in gpio mode should be made through gpiolib.
-
-Key Features of gpiomux
-=======================
-
-- A consistent interface across all generations of msm.  Drivers can expect
-the same results on every target.
-- gpiomux plays nicely with gpiolib.  Functions that should belong to gpiolib
-are left to gpiolib and not duplicated here.  gpiomux is written with the
-intent that gpio_chips will call gpiomux reference-counting methods
-from their request() and free() hooks, providing full integration.
-- Tabular configuration.  Instead of having to call gpio_tlmm_config
-hundreds of times, gpio configuration is placed in a single table.
-- Per-gpio sleep.  Each gpio is individually reference counted, allowing only
-those lines which are in use to be put in high-power states.
-- 0 means 'do nothing': all flags are designed so that the default memset-zero
-equates to a sensible default of 'no configuration', preventing users
-from having to provide hundreds of 'no-op' configs for unused or
-unwanted lines.
-
 Usage
 =====
 
-To use gpiomux, provide configuration information for relevant gpio lines
-in the msm_gpiomux_configs table.  Since a 0 equates to "unconfigured",
-only those lines to be managed by gpiomux need to be specified.  Here
-is a completely fictional example:
+To use gpiomux, do the following before the msmgpio gpiochips probe:
 
-struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
-	[12] = {
-		.active = GPIOMUX_VALID | GPIOMUX_DRV_8MA | GPIOMUX_FUNC_1,
-		.suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN,
-	},
-	[34] = {
-		.suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN,
+- Call msm_gpiomux_init to allocate needed resources.
+- Install one or more sets of gpiomux configuration data via
+  msm_gpiomux_install and/or msm_gpiomux_write.
+
+Failing to finish these steps before the probe of msmgpio can result in calls
+from msmgpio to gpiomux to try and activate lines which have not yet
+been configured.
+
+A basic gpiomux setting is described by a gpiomux_setting structure.
+A gpiomux configuration is a group of those settings (one for each power
+state of the board) paired with a specific gpio, like so:
+
+struct msm_gpiomux_config gpio123_config __initdata = {
+	.gpio = 123,
+	.settings = {
+		[GPIOMUX_ACTIVE] = {
+			.func = GPIOMUX_FUNC_GPIO,
+			.drv  = GPIOMUX_DRV_2MA,
+			.pull = GPIOMUX_PULL_NONE,
+			.dir  = GPIOMUX_OUT_HIGH,
+		},
+		[GPIOMUX_SUSPENDED] = {
+			.func = GPIOMUX_FUNC_3,
+			.drv  = GPIOMUX_DRV_8MA,
+			.pull = GPIOMUX_PULL_DOWN,
+		},
 	},
 };
 
-To indicate that a gpio is in use, call msm_gpiomux_get() to increase
-its reference count.  To decrease the reference count, call msm_gpiomux_put().
-
 The effect of this configuration is as follows:
 
-When the system boots, gpios 12 and 34 will be initialized with their
-'suspended' configurations.  All other gpios, which were left unconfigured,
-will not be touched.
+- When the system boots, gpio 123 will be put into the SUSPENDED setting.
+- When the reference count for gpio 123 rises above 0, the ACTIVE setting
+  will be applied.
+- When the reference count falls back to 0, the SUSPENDED setting will be
+  reapplied.
 
-When msm_gpiomux_get() is called on gpio 12 to raise its reference count
-above 0, its active configuration will be applied.  Since no other gpio
-line has a valid active configuration, msm_gpiomux_get() will have no
-effect on any other line.
+The reference count rises when msm_gpiomux_get() is called and falls
+when msm_gpiomux_put() is called.  msmgpio has hooks to these functions
+in its gpiolib implementation.  This means that when you call gpio_request()
+on an msmgpio, msm_gpiomux_get() is automatically called on your behalf.
+Similarly, when you call gpio_free(), msm_gpiomux_put() is called for you.
+This allows generic drivers to obtain low-level management of msmgpio lines
+without having to be aware of the gpiomux layer.
 
-When msm_gpiomux_put() is called on gpio 12 or 34 to drop their reference
-count to 0, their suspended configurations will be applied.
-Since no other gpio line has a valid suspended configuration, no other
-gpio line will be effected by msm_gpiomux_put().  Since gpio 34 has no valid
-active configuration, this is effectively a no-op for gpio 34 as well,
-with one small caveat, see the section "About Output-Enable Settings".
+Note that the .dir field is ignored if .func != GPIOMUX_FUNC_GPIO, since
+software control of gpios is allowed only in GPIO mode.  By selecting any
+other .func, you assign the gpio to another piece of hardware and lose
+control of it from gpiolib.  You can still reserve such gpios with gpio_request
+to prevent other modules from using them while they're in such a state,
+but other gpiolib functions will not behave as you expect if .func != GPIO.
 
-All of the GPIOMUX_VALID flags may seem like unnecessary overhead, but
-they address some important issues.  As unused entries (all those
-except 12 and 34) are zero-filled, gpiomux needs a way to distinguish
-the used fields from the unused.  In addition, the all-zero pattern
-is a valid configuration!  Therefore, gpiomux defines an additional bit
-which is used to indicate when a field is used.  This has the pleasant
-side-effect of allowing calls to msm_gpiomux_write to use '0' to indicate
-that a value should not be changed:
-
-  msm_gpiomux_write(0, GPIOMUX_VALID, 0);
-
-replaces the active configuration of gpio 0 with an all-zero configuration,
-but leaves the suspended configuration as it was.
+If a configuration is omitted, nothing will happen at the relevant transitions.
+This allows for the creation of 'static configurations' which do not
+change as the line is requested and freed.
 
 Static Configurations
 =====================
 
 To install a static configuration, which is applied at boot and does
 not change after that, install a configuration with a suspended component
-but no active component, as in the previous example:
+but no active component:
 
-	[34] = {
-		.suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN,
+	.gpio = ...,
+	.settings = {
+		[GPIOMUX_SUSPENDED] = {
+			...
+		},
 	},
 
 The suspended setting is applied during boot, and the lack of any valid
@@ -153,24 +120,3 @@
 This mechanism allows for "auto-request" of gpiomux lines via gpiolib
 when it is suitable.  Drivers wishing more exact control are, of course,
 free to also use msm_gpiomux_set and msm_gpiomux_get.
-
-About Output-Enable Settings
-============================
-
-Some msm targets do not have the ability to query the current gpio
-configuration setting.  This means that changes made to the output-enable
-(OE) bit by gpiolib cannot be consistently detected and preserved by gpiomux.
-Therefore, when gpiomux applies a configuration setting, any direction
-settings which may have been applied by gpiolib are lost and the default
-input settings are re-applied.
-
-For this reason, drivers should not assume that gpio direction settings
-continue to hold if they free and then re-request a gpio.  This seems like
-common sense - after all, anybody could have obtained the line in the
-meantime - but it needs saying.
-
-This also means that calls to msm_gpiomux_write will reset the OE bit,
-which means that if the gpio line is held by a client of gpiolib and
-msm_gpiomux_write is called, the direction setting has been lost and
-gpiolib's internal state has been broken.
-Release gpio lines before reconfiguring them.
diff --git a/Documentation/arm/msm/kgsl-sysfs.txt b/Documentation/arm/msm/kgsl-sysfs.txt
new file mode 100644
index 0000000..c572312
--- /dev/null
+++ b/Documentation/arm/msm/kgsl-sysfs.txt
@@ -0,0 +1,98 @@
+This document lists details for the device specific sysfs attributes
+created by the KGSL GPU driver.
+
+- /sys/devices/platform/kgsl/vmalloc
+  The total amount of vmalloc()ed memory currently allocated by the driver
+  (in bytes)
+
+- /sys/devices/platform/kgsl/vmalloc_max
+  The maximum amount of vmalloc()ed memory allocated at any one
+  time by the driver since the system was booted (in bytes)
+
+- /sys/devices/platform/kgsl/coherent
+  The total amount of coherent DMA memory currently allocated by the driver
+  (in bytes)
+
+- /sys/devices/platform/kgsl/coherent_max
+  The maximum amount of coherent DMA memory allocated at any one
+  time by the driver since the system was booted (in bytes)
+
+
+- /sys/devices/platform/kgsl/histogram
+  A histogram of the sizes of vmalloc allocations by the driver
+  since the system was booted.  The allocations are grouped by the order
+  of the allocation size in pages.  For example, order 0 are 1 page
+  allocations, order 1 are 2 page allocations, order 2 are 4 page allocations,
+  and so forth, up to order 16 (32768) pages.
+
+- /sys/devices/platform/kgsl/proc
+  This directory contains individual entries for each active rendering
+  process.  Rendering instances are created for each unique process that
+  opens the GPU devices, and are named for the id of the creating process.
+  In the driver, memory allocations are owned by the process that allocates
+  them, and outstanding memory is garbage collected when the process closes
+  the device.
+
+  - /sys/devices/platform/kgsl/proc/NN/vmalloc
+    The total amount of vmalloc memory currently allocated by the process
+    (in bytes)
+
+  - /sys/devices/platform/kgsl/proc/NN/vmalloc_max
+    The maximum amount of vmalloc memory allocated at any one
+    time by the process since it was created (in bytes)
+
+  - /sys/devices/platform/kgsl/proc/NN/exmem
+    The total amount of external memory devices currently mapped by the process
+    (in bytes).  This includes PMEM, ASHMEM and external memory pointers from
+    userspace.
+
+  - /sys/devices/platform/kgsl/proc/NN/exmem_max
+    The maximum amount of external memory devices allocated at any one
+    time by the process since it was created (in bytes).  This includes PMEM,
+    ASHMEM and external memory pointers from userspace.
+
+  - /sys/devices/platform/kgsl/proc/NN/flushes
+    The total number of cache flushes performed by this process since it
+    was created.
+
+- /sys/devices/platform/kgsl/pagetables
+  This directory contains individual entries for each active pagetable.
+  There will always be a global pagetable with ID 0.  If per-process
+  pagetables are not enabled, pagetable ID 0 will also be the default
+  pagetable for all processes.  If per-process pagetables are enabled,
+  there will be an entry for each pagetable, named after the ID of the
+  process that created it.
+
+  - /sys/devices/platform/kgsl/pagetables/NN/entries
+    The number of concurrent entries mapped in the GPU MMU.
+
+  - /sys/devices/platform/kgsl/pagetables/NN/mapped
+    The number of bytes currently mapped in the GPU MMU.
+
+  - /sys/devices/platform/kgsl/pagetables/NN/va_range
+    The virtual address size of the MMU pagetable (in bytes).
+
+  - /sys/devices/platform/kgsl/pagetables/NN/max_mapped
+    The maximum number of bytes concurrently mapped in the GPU MMU since
+    the pagetable was created.
+
+  - /sys/devices/platform/kgsl/pagetables/NN/max_entries
+    The maximum number of entries concurrently mapped in the GPU MMU since
+    the pagetable was created.
+
+- /sys/devices/platform/kgsl/msm_kgsl/
+  Each individual GPU device (2D or 3D) will have its own device node in
+  this directory.  All platforms will have kgsl-3d0 (3D device), some
+  devices may have 1 2D device (kgsl-2d0) and others might add a second 2D
+  device (kgsl-2d1).
+
+  - /sys/devices/platform/kgsl/msm_kgsl/kgsl-XXX/pwrnap
+  Controls the system ability to nap (lightly sleep between frames).  1
+  indicates napping is enabled, 0 indicates it is disabled.  Write a 1 or
+  a 0 to the file to control napping.
+
+  - /sys/devices/platform/kgsl/msm_kgsl/kgsl-XXX/gpuclk
+  Shows the last active requested speed of the GPU clock in HZ, does not
+  actually measure the current clock rate. Write a clock speed to the file
+  corresponding to a supported platform power level to change to that power
+  level. The bandwidth vote will also be adjusted.
diff --git a/Documentation/arm/msm/msm_rng-driver.txt b/Documentation/arm/msm/msm_rng-driver.txt
new file mode 100644
index 0000000..3e7d1e9
--- /dev/null
+++ b/Documentation/arm/msm/msm_rng-driver.txt
@@ -0,0 +1,75 @@
+Introduction:
+=============
+
+The msm_rng device driver handles random number generation
+using hardware present in MSM chipsets.
+
+Hardware description:
+=====================
+
+The supported hardware is a macro block within a system-on-a-chip (SoC).
+The hardware is pseudo random number generator (PRNG) with four oscillators
+setup with a linear feedback shift register (LFSR).
+The hardware must be initially configured once for normal operation and
+a 32bit FIFO is read to obtain hardware generated pseudo random numbers.
+Currently the driver configures the hardware registers during initialization
+and the future plan is to have the boot loader configure these registers and
+write lock them so only host OS can read them and the driver writes will be
+ignored.
+
+Software description
+====================
+
+The driver is based on the platform_driver model.  It registers an entry,
+exit and probe functions. Once the probe function is called, the driver
+registers a callback function with the hwrng (Hardware Random Number Generator)
+subsystem that is called when the hardware device (i.e. /dev/hw_random) is
+requesting random data from this device.
+Once the callback is issued from the hwrng subsystem, the driver checks to
+make sure the hardware has random data available and determines the maximum
+data it can return and returns that much data back.
+
+Power Management
+================
+
+Initially, no services are provided in the area of power management.
+
+SMP/multi-core
+==============
+
+The locking mechanism for the hwrng operations is taken care of by the hwrng
+framework. There are no SMP situations within the driver that need addressing.
+
+Driver parameters
+=================
+
+This driver is built and statically linked into the kernel; therefore,
+there are no module parameters supported by this driver.
+
+There are no kernel command line parameters supported by this driver.
+
+Config options
+==============
+
+This driver is enabled by the kernel config option CONFIG_HW_RANDOM_MSM.
+The option CONFIG_HW_RANDOM_MSM depends on HW_RANDOM && ARCH_MSM.
+
+Dependencies:
+=============
+
+This driver depends on the HW_RANDOM subsystem to register with and get
+callbacks to request random data.
+
+User space utilities:
+=====================
+
+The driver alone does not feed random numbers into kernel but just provides a
+method to get random numbers to a known device (i.e. /dev/hw_random). A user-
+space utility is required to monitor the /dev/random device entropy pool and
+feed it from the /dev/hw_random device. This application also must perform some
+sort of sanity checking on the returned data to make sure the data is not all
+the same.
+
+There is currently a GPL v2 tool called rng-tools that has a daemon called,
+"rngd" that performs this functionality. There is also a test tool in this
+package that tests the whole random subsystem.
diff --git a/Documentation/arm/msm/pil.txt b/Documentation/arm/msm/pil.txt
new file mode 100644
index 0000000..5b0b527
--- /dev/null
+++ b/Documentation/arm/msm/pil.txt
@@ -0,0 +1,267 @@
+Introduction
+============
+
+The PIL (Peripheral Image Loader) driver loads peripheral images into memory
+and interfaces with the Peripheral Authentication Service (PAS) to
+authenticate and reset peripherals embedded in the SoC.
+
+The PAS could either be running under secure mode in the application
+processor (secure boot support) or be running as a non-secure kernel driver
+(non-secure boot support).
+
+The PIL driver also does housekeeping to handle cases where more than one
+client driver is using the same peripheral.
+
+Some examples of peripherals are modem, DSP and sensors.
+
+Hardware description
+====================
+
+The memory used by the peripherals for code and data storage will be
+accessible as normal memory to the application processor.
+
+The non-secure code (Linux kernel) will have read/write permissions to the
+peripheral memory by default.
+
+The PAS will have access to a MPU (memory protection unit) that can lock away
+the pages of memory from the Linux kernel. It will also have access to
+registers that can reset each peripheral.
+
+Software description
+====================
+
+The PAS provides the following three APIs:
+
+* Init image - Takes as input the peripheral id and firmware metadata and
+  returns a status indicating the authenticity of the firmware metadata.  The
+  firmware metadata consists of a standard ELF32 header followed by a program
+  header table and an optional blob of data used to authenticate the metadata
+  and the rest of the firmware.
+
+* Verify segment - Takes as input the firmware segment id and the length of
+  the segment. Authenticates whatever amount (specified by the "length"
+  parameter) of the firmware segment that has been loaded and removes
+  non-secure mode read/write permissions for the pages belonging to the
+  firmware segment. Allows multiple calls for the same firmware segment to
+  allow partial loading and authentication.
+
+* Auth and Reset - Verifies all the necessary firmware segments have been
+  loaded and authenticated and then resets the peripheral.
+
+The user space is expected to provide the firmware metadata and firmware
+segments as separate files on persistent storage. See "Interface" section for
+further details.
+
+The PIL driver will use the request_firmware API provided by the Linux kernel
+to read the firmware and firmware metadata from persistent storage.
+
+When a client driver requests for a peripheral to be enabled, the PIL driver
+increments the reference count for that peripheral, loads the firmware
+metadata and calls the PAS Init Image API that initializes the authentication
+state machine using the firmware metadata.
+
+If the initialization succeeds, the PIL driver loads the appropriate firmware
+segments into their respective memory locations and call the PAS Verify
+segment API on each of the loaded segments to authenticate and lock it.
+
+After all the firmware segments have been successfully loaded and
+authenticated, the PAS Auth and Reset API is called to reset the peripheral
+and initiate its boot sequence.
+
+A peripheral enable request to the PIL driver will block until it succeeds
+(or fails) to initiate the peripheral boot sequence but will NOT block until
+the peripheral is ready. It is not possible to block until a peripheral is
+ready since the semantics of "ready" is subjective to the caller.
+
+The PIL driver will maintain a reference count for each of the peripherals.
+So, if a peripheral is already under use and another client driver requests
+for the peripheral to be enabled, the PIL driver will immediately return a
+value to indicate success.
+
+When all the client drivers of a particular peripheral no longer need the
+peripheral and the reference count reaches zero, the PIL driver can cleanly
+shut down the peripheral. Since a lot of drivers in their current state can't
+handle a peripheral restart, the PIL driver will never let the reference
+count go back to zero.
+
+All information about a peripheral, like firmware filenames, peripheral ID
+passed to PAS, etc, will be hard coded in the PIL driver.
+
+All the PIL APIs will execute in the context of the caller. This includes
+calls from the PIL driver to the PAS driver. The PAS driver might decide to
+switch into secure mode from a separate workqueue or in the same context as
+the caller, but that shouldn't have any implications for the PIL API callers
+since all the PIL APIs are blocking calls.
+
+Dependencies:
+-------------
+* Firmware class (CONFIG_FW_LOADER) for using the request_firmware API to
+  load firmware from persistent storage.
+* PAS to authenticate firmware and bring a peripheral out of reset.
+
+Error cases:
+------------
+The PIL driver could fail to enable a peripheral for several reasons like not
+having enough memory to load firmware and metadata, being unable to
+communicate with the PAS, the PAS returning with an error, etc. For all
+possible error cases, the PIL driver does not perform any retries and returns
+an appropriate error code. The client drivers should always check for success
+before trying to access the peripheral.
+
+Design
+======
+
+Design goals:
+-------------
+* The PIL driver must be agnostic to the actual format and method used to
+  authenticate the firmware.
+* Allow for future expansion to support demand loading of parts of firmware
+  for each peripheral.
+* Move most of the work into the preprocessing/building stage of the firmware.
+* Provide an API to the client drivers that absolves them from having to know
+  the structure or names of the firmware in persistent storage.
+* Handle multiple client drivers wanting to enable the same peripheral.
+
+
+Design reasons:
+---------------
+The user space is expected to provide the firmware metadata and segments as
+separate files for the following reasons:
+* Don't need to load the whole ELF file if the authentication info is
+  invalid.
+* Works better during low memory conditions since the amount of memory used
+  at any given instant when loading one segment at a time is smaller than
+  loading the whole ELF file.
+* Since an ELF segment in memory can be much bigger than on file, having a
+  flat binary would waste a lot of space due to zero-fills.
+* Allows for future enhancements to the loading procedure.
+
+Design tradeoffs:
+-----------------
+* With appropriate changes to the request_firmware API, the firmware blobs
+  could be directly loaded into the right memory location. But due to the
+  additional work and community approval that would be needed for modifying
+  the request_firmware API, we load the firmware blobs into kernel memory and
+  then copy them into the appropriate locations.
+
+Alternate designs:
+------------------
+One of the alternate designs that were considered required the firmware to be
+a flat binary. Although this design would simplify the PIL driver, it would
+result in the waste of a lot of persistent storage space (due to large
+zero-fills), prevent demand loading of segments in the future and use a lot
+more memory while loading the firmware.
+
+Software layering:
+------------------
+The peripheral authentication, reset and shutdown implementation is factored
+away into a Peripheral Authentication Service driver to allow the PIL driver
+to be agnostic of secure vs. non-secure boot and the mechanisms needed for
+communicating with any code that might be running in secure mode.
+
+Power Management
+================
+
+Some of the peripherals might support being turned off when not in use.
+Support for this might be disabled in the initial implementation of the PIL
+driver since many of the existing drivers can not handle peripheral restart.
+
+SMP/multi-core
+==============
+
+Will use mutexes to protected data that might be shared (reference count,
+etc).
+
+Security
+========
+
+The PIL driver must validate the physical memory addresses specified in the
+ELF and program header table before loading firmware segments to make sure
+it's not overwriting any memory used by the kernel and possibly PMEM regions
+(if it can be done without being an ugly hack). The PIL driver might need to
+maintain a white list or black list of physical memory address ranges to
+perform the address validation.
+
+Performance
+===========
+
+As mentioned in the design section, the loading of firmware segments is not
+optimal and has room for improvement.
+
+Interface
+=========
+
+In kernel APIs:
+void * pil_get(char *peripheral_name)
+	- Enables (if not already enabled) a peripheral and returns a handle
+	  that can be used to disable the peripheral at a later time. If
+	  peripheral can't be enabled successfully, then returns an error
+	  (use IS_ERR) indicating the reason.
+
+void pil_put(void *peripheral_handle)
+	- Inform PIL that this client no longer needs the peripheral to be
+	  active. Does not necessarily mean that the peripheral would be
+	  disabled or powered off.
+
+
+User space APIs:
+All firmware must be located in the path that is expected by the hotplug (or
+compatible) daemon. A hotplug (or compatible) daemon should be running and be
+able to handle events from the kernel requesting for a firmware file.
+
+The basename of the firmware files will depend on the peripheral. For a given
+peripheral, the metadata filename should end with a ".mdt" and the firmware
+segment files should end with ".bXX" where XX denotes the index of the
+firmware segment starting from 0.
+
+Android hotplug compatible daemon expects the firmware files to be under
+/etc/firmware.
+
+Driver parameters
+=================
+
+No module or kernel command line parameters supported.
+
+Config options
+==============
+
+This driver is enabled using the MSM_PIL kernel config option and will
+depend on the CONFIG_FW_LOADER being available.
+
+Dependencies
+============
+
+Depends on firmware class module for the request_firmware API.
+
+Interacts with the PAS to authenticate the firmware and to initiate the boot
+sequence of a peripheral.
+
+Doesn't communicate with other processors since the secure code, if any, will
+be running on the application processor cores.
+
+User space utilities
+====================
+
+None.
+
+Other
+=====
+
+The firmware_class driver might be changed in the future to directly load the
+firmware into memory locations provided by the caller of request_firmware().
+
+Known issues
+============
+
+Since support for cleanly shutting down peripherals is yet to be added, the
+reference count of peripherals will never be allowed to go to zero once it
+becomes non-zero.
+
+To do
+=====
+
+* Add support for turning off peripherals when they are not in use.
+* Modify request_firmware() to directly copy firmware blobs into the
+  appropriate memory locations.
+* Add support for demand loading of firmware segments.
+* Add support for forced peripheral restarts.
diff --git a/Documentation/arm/msm/rpm.txt b/Documentation/arm/msm/rpm.txt
new file mode 100644
index 0000000..9c9511f
--- /dev/null
+++ b/Documentation/arm/msm/rpm.txt
@@ -0,0 +1,157 @@
+Introduction
+============
+
+Resource Power Manager (RPM)
+
+RPM is a dedicated hardware engine for managing shared SoC resources,
+which includes buses, clocks, power rails, etc.  The goal of RPM is
+to achieve the maximum power savings while satisfying the SoC's
+operational and performance requirements.  RPM accepts resource
+requests from multiple RPM masters.  It arbitrates and aggregates the
+requests, and configures the shared resources.  The RPM masters are
+the application processor, the modem processor, as well as some
+hardware accelerators.
+
+The RPM driver provides an API for interacting with RPM.  Kernel code
+calls the RPM driver to request RPM-managed, shared resources.
+Kernel code can also register with the driver for RPM notifications,
+which are sent when the status of shared resources change.
+
+Hardware description
+====================
+
+RPM exposes a separate region of registers to each of the RPM masters.
+In general, each register represents some shared resource(s).  At a
+very basic level, a master requests resources by writing to the
+registers, then generating an interrupt to RPM.  RPM processes the
+request, writes acknowledgement to the registers, then generates an
+interrupt to the master.
+
+In addition to the master-specific regions, RPM also exposes a shared
+region that contains the current status of the shared resources.  Only
+RPM can write to the status region, but every master can read from it.
+
+RPM contains internal logics that aggregate and arbitrate among
+requests from the various RPM masters.  It interfaces with the PMIC,
+the bus arbitration block, and the clock controller block in order to
+configure the shared resources.
+
+Software description
+====================
+
+The RPM driver encapsulates the low level RPM interactions, which
+rely on reading/writing registers and generating/processing
+interrupts, and provides a higher level synchronuous set/clear/get
+interface.  Most functions take an array of id-value pairs.
+The ids identify the RPM registers which would correspond to some
+RPM resources, the values specify the new resource values.
+
+The RPM driver synchronizes accesses to RPM.  It protects against
+simultaneous accesses from multiple tasks, on SMP cores, in task
+contexts, and in atomic contexts.
+
+Design
+======
+
+Design goals:
+- Encapsulate low level RPM interactions.
+- Provide a synchronuous set/clear/get interface.
+- Synchronize simultaneous software accesses to RPM.
+
+Power Management
+================
+
+RPM is part of the power management architecture for MSM 8660.  RPM
+manages shared system resources to lower system power.
+
+SMP/multi-core
+==============
+
+The RPM driver uses mutex to synchronize client accesses among tasks.
+It uses spinlocks to synchronize accesses from atomic contexts and
+SMP cores.
+
+Security
+========
+
+None.
+
+Performance
+===========
+
+None.
+
+Interface
+=========
+
+msm_rpm_get_status():
+The function reads the shared status region and returns the current
+resource values, which are the arbitrated/aggregated results across
+all RPM masters.
+
+msm_rpm_set():
+The function makes a resource request to RPM.
+
+msm_rpm_set_noirq():
+The function is similar to msm_rpm_set() except that it must be
+called with interrupts masked.  If possible, use msm_rpm_set()
+instead, to maximize CPU throughput.
+
+msm_rpm_clear():
+The function makes a resource request to RPM to clear resource values.
+Once the values are cleared, the resources revert back to their default
+values for this RPM master.  RPM internally uses the default values as
+the requests from this RPM master when arbitrating and aggregating with
+requests from other RPM masters.
+
+msm_rpm_clear_noirq():
+The function is similar to msm_rpm_clear() except that it must be
+called with interrupts masked.  If possible, use msm_rpm_clear()
+instead, to maximize CPU throughput.
+
+msm_rpm_register_notification():
+The function registers for RPM notification.  When the specified
+resources change their status on RPM, RPM sends out notifications
+and the driver will "up" the semaphore in struct
+msm_rpm_notification.
+
+msm_rpm_unregister_notification():
+The function unregisters a notification.
+
+msm_rpm_init():
+The function initializes the RPM driver with platform specific data.
+
+Driver parameters
+=================
+
+None.
+
+Config options
+==============
+
+MSM_RPM
+
+Dependencies
+============
+
+None.
+
+User space utilities
+====================
+
+None.
+
+Other
+=====
+
+None.
+
+Known issues
+============
+
+None.
+
+To do
+=====
+
+None.
diff --git a/Documentation/arm/msm/tsif.txt b/Documentation/arm/msm/tsif.txt
new file mode 100644
index 0000000..9f6827c
--- /dev/null
+++ b/Documentation/arm/msm/tsif.txt
@@ -0,0 +1,231 @@
+TSIF driver serves piece of hardware found in Qualcomm MSM's.
+It deals with Digital Mobile Broadcast.
+
+If you are dealing with Qualcomm MSM that have relevant piece of hardware,
+read on.
+
+There are various Digital Mobile Broadcast (DMB) systems developed to receive
+audio and/or television broadcast programs by Mobile Station Modem (MSM).
+(in simplified words - cellular phone)
+
+All of these systems have similar architecture. They use radio link which
+is different from primary handset link and hence use the additional antenna.
+RF signal from the broadcast tuner goes to de-modulator.
+Regardless of actual tuner and de-modulator, all systems present
+ITU-T H.222.0 (also known as MPEG2) Transport Stream (HTS)
+to the Mobile Station Modem (MSM).
+
+TSIF stands for Transport Stream Interface;
+this is hardware block in MSM that receives HTS signal from the de-modulator.
+
+TSIF use serial interface with de-modulator;
+it buffers data received in internal registers.
+TSIF support data copying from its internal registers to the RAM
+with the Data Mover (DM).
+
+TSIF driver prevent MSM from sleeping while TSIF hardware is active.
+To achieve this, driver holds wake lock.
+
+For access to TSIF data, TSIF driver provides kernel API
+that may be used by another kernel module. As example for API usage,
+simple TSIF chardev adapter provided. It provides character device
+/dev/tsif0. This device may be opened by single process at a time.
+When read, it provides TS stream.
+
+Quick start:
+
+### copy modules to the target
+adb push msm_tsif.ko /data/local/tmp/
+adb push tsif_chrdev.ko /data/local/tmp/
+### Load modules on the target:
+adb shell mount -t debugfs debugfs /sys/kernel/debug
+adb shell insmod /data/local/tmp/msm_tsif.ko
+adb shell insmod /data/local/tmp/tsif_chrdev.ko
+### Run capture:
+adb shell cat /dev/tsif0 > /data/local/tmp/tsif.dump
+
+
+# tests:
+adb shell mount -t debugfs debugfs /sys/kernel/debug
+adb shell rmmod tsif_chrdev
+adb shell rmmod msm_tsif
+adb shell insmod /data/local/tmp/msm_tsif.ko
+adb shell insmod /data/local/tmp/tsif_chrdev.ko
+adb shell 'echo 60 > /sys/devices/platform/msm_tsif.0/time_limit'
+adb shell 'echo "16 * 8" > /sys/devices/platform/msm_tsif.0/buf_config'
+
+# separate xterm:
+watch adb shell cat /sys/devices/platform/msm_tsif.0/stats
+# separate xterm:
+watch adb shell cat /sys/kernel/debug/msm_tsif.0/dma
+# separate xterm:
+adb shell dd if=/dev/tsif0 of=/dev/null
+
+Mode of operation
+
+TSIF hardware have 2 modes of operation: mode1 and mode 2.
+They differ in serial interface signals. Mode used should match demodulator
+chip interface.
+
+In addition to these 2 modes of operation, TSIF driver have pseudo-mode 3
+that means "debug mode" where all operation controlled through debug interfaces.
+Client configure TSIF mode of operation using tsif_set_mode().
+Alternatively, mode of operation may be configured using device attribute file:
+echo 1 > /sys/devices/platform/msm_tsif.0/mode
+
+Time limit
+
+TSIF driver maintains time limit value. Its value corresponds
+to the TSIF_TIME_LIMIT register in TSIF hardware.
+Value in ticks of tsif_ref_clk. If time between the end of previous
+packet and end of current one exceeds this value, timeout status reported
+for the current TSIF packet.
+Client configure TSIF time limit using tsif_set_time_limit().
+Alternatively, time limit may be configured using device attribute file:
+echo 100 > /sys/devices/platform/msm_tsif.0/time_limit
+
+TSIF packet format
+
+TSIF driver uses 192 byte packets; where first 188 packets is HTS packet;
+last 4 bytes consists of :
+3 bytes TTS in bytes 188..190; and status byte ib byte 191.
+
+Status byte contains the following fields:
+Bit   Name        Comment
+0     Valid	    Always set to 1 to indicate valid HTS packet and status.
+                    If set to 0, this packet is not valid and should be ignored
+1     First packet  When set, indicates 1-st packet of a new stream or
+                    1-st valid packet after one or more packets were lost.
+2     Overflow	    When set, indicates overflow condition in TSIF hardware;
+                    one or more packets were lost. Current packet is valid.
+3     Error	    Indicates the tsif_error signal status
+4     Null	    Indicates the tsif_null signal status
+5     Reserved	    Don't care
+6     Timeout	    Indicates the 1-st packet after timeout.
+                    First packet flag will also be set.
+
+Debug facilities
+
+TSIF driver provides extensive debugging facilities to assist debug both
+TSIF input and TSIF client interfaces. 2 mechanisms used:
+
+Device attribute, accessible through usual /sys hierarchy under
+/sys/devices/platform/msm_tsif.0, provides status and statistics information.
+
+Debugfs exposes more hardware and software details. In order to use debugfs,
+one need to mount it:
+
+adb shell mount -t debugfs debugfs /sys/kernel/debug
+
+When debugfs mounted, TSIF entries may be found under
+/sys/kernel/debug/msm_tsif.0
+
+Register access
+
+All TSIF hardware registers accessible through debugfs.
+$ adb shell ls -l /sys/kernel/debug/msm_tsif.0
+-r--r--r-- root     root            0 1980-01-07 16:15 dma
+--w------- root     root            0 1980-01-07 16:15 action
+-r--r--r-- root     root            0 1980-01-07 16:15 gpios
+-r-------- root     root            0 1980-01-07 16:15 data_port
+-r--r--r-- root     root            0 1980-01-07 16:15 test_current
+-rw-r--r-- root     root            0 1980-01-07 16:15 test_export
+--w------- root     root            0 1980-01-07 16:15 test_reset
+-rw-r--r-- root     root            0 1980-01-07 16:15 test_mode
+-rw-r--r-- root     root            0 1980-01-07 16:15 test_ctl
+-rw-r--r-- root     root            0 1980-01-07 16:15 lpbk_data
+-rw-r--r-- root     root            0 1980-01-07 16:15 lpbk_flags
+-rw-r--r-- root     root            0 1980-01-07 16:15 clk_ref
+-rw-r--r-- root     root            0 1980-01-07 16:15 time_limit
+-rw-r--r-- root     root            0 1980-01-07 16:15 sts_ctl
+
+TSIF clocks are off when TSIF is not running.
+To control TSIF through low level register access, it should be set to the
+mode 3 ("debug"); in addition, TSIF start/stop actions may be executed using
+debugfs action file:
+
+adb shell 'echo open > /sys/kernel/debug/msm_tsif.0/action'
+
+Possible actions are "open" and "close".
+
+DMA activity
+
+DMA activity may be queried using debugfs dma file:
+
+$ adb shell cat /sys/kernel/debug/msm_tsif.0/dma
+ri  16 | wi  24 | dmwi  40 | [ 24]{ 32} [ 32]{ 40}
+
+This file provides ri/wi/dmwi indexes
+(dmwi is for Data Mover write index - index for first location where
+next DMA may be scheduled);
+and 2 Data Mover transfer tasks, each in [wi] {next_wi} format.
+Here, wi is index DMA is scheduled for; next_wi is where driver's
+wi will be set after DMA completion.
+
+Driver status
+
+Driver status available through stats device attribute:
+
+$ adb shell cat /sys/devices/platform/msm_tsif.0/stats
+Device       msm_tsif.0
+Mode       = 1
+Time limit = 60
+State        running
+Client     = bf036f68
+Pkt/Buf    = 64
+Pkt/chunk  = 8
+--statistics--
+Rx chunks  = 3288898
+Overflow   = 4606
+Lost sync  = 0
+Timeout    = 1
+DMA error  = 0
+Soft drop  = 0
+IFI        = 48
+--debug--
+GLBL_CLK_ENA     = 0x637dfe23
+ROW_RESET        = 0x000008c1
+CLK_HALT_STATEB  = 0xde6d80ff
+TV_NS_REG        = 0xf8e00b44
+TSIF_NS_REG      = 0x00000b40
+
+GPIO
+
+Current GPIO values may be read using debugfs gpio file:
+$ adb shell cat /sys/kernel/debug/msm_tsif.0/gpios
+       tsif_clk: 0
+        tsif_en: 0
+      tsif_data: 0
+      tsif_sync: 0
+
+In normal regime, signals changed too fast for this facility to provide
+change by change log; it should be seen as random time capture.
+When debugging TSIF input connectivity, it may be helpful to run
+
+watch -d adb shell cat /sys/kernel/debug/msm_tsif.0/gpios
+
+to see if input ever changes. If nothing changes at all; it is indication
+for mis-configured input.
+
+Another tip: in case of wire connection between components, one may connect
+TSIF input pin to logical 1 instead of actual signal source,
+to verify this is the pin required.
+
+Inter frame interval
+
+To estimate incoming bit rate, TSIF driver measure average time interval
+between packets. Interval measured in tsif_ref_clk ticks. Actually, TSIF
+gets TTS from 1-st and last packets in chunk and use this time to calculate
+inter frame interval.
+Inter frame interval available as part of device statistics.
+
+Tip: to measure tsif_ref_clk  frequency, this approach may be used:
+
+adb shell cat /sys/kernel/debug/msm_tsif.0/clk_ref; sleep 10; adb shell cat /sys/kernel/debug/msm_tsif.0/clk_ref
+0x8db70ec8
+0x8dc6974b
+
+Then, calculate (0x8dc6974b - 0x8db70ec8)/10 that is 101798.7 Hz
+
+
+