/* * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. * Copyright 2011 Florian Tobias Schandinat * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; * either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * clock and PLL management functions */ #include #include #include #include "via_clock.h" #include "global.h" #include "debug.h" static const char *via_slap = "Please slap VIA Technologies to motivate them " "releasing full documentation for your platform!\n"; static inline u32 cle266_encode_pll(struct via_pll_config pll) { return (pll.multiplier << 8) | (pll.rshift << 6) | pll.divisor; } static inline u32 k800_encode_pll(struct via_pll_config pll) { return ((pll.divisor - 2) << 16) | (pll.rshift << 10) | (pll.multiplier - 2); } static inline u32 vx855_encode_pll(struct via_pll_config pll) { return (pll.divisor << 16) | (pll.rshift << 10) | pll.multiplier; } static inline void cle266_set_primary_pll_encoded(u32 data) { via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ via_write_reg(VIASR, 0x46, data & 0xFF); via_write_reg(VIASR, 0x47, (data >> 8) & 0xFF); via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ } static inline void k800_set_primary_pll_encoded(u32 data) { via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ via_write_reg(VIASR, 0x44, data & 0xFF); via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); via_write_reg(VIASR, 0x46, (data >> 16) & 0xFF); via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ } static inline void cle266_set_secondary_pll_encoded(u32 data) { via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ via_write_reg(VIASR, 0x44, data & 0xFF); via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ } static inline void k800_set_secondary_pll_encoded(u32 data) { via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ via_write_reg(VIASR, 0x4A, data & 0xFF); via_write_reg(VIASR, 0x4B, (data >> 8) & 0xFF); via_write_reg(VIASR, 0x4C, (data >> 16) & 0xFF); via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ } static inline void set_engine_pll_encoded(u32 data) { via_write_reg_mask(VIASR, 0x40, 0x01, 0x01); /* enable reset */ via_write_reg(VIASR, 0x47, data & 0xFF); via_write_reg(VIASR, 0x48, (data >> 8) & 0xFF); via_write_reg(VIASR, 0x49, (data >> 16) & 0xFF); via_write_reg_mask(VIASR, 0x40, 0x00, 0x01); /* disable reset */ } static void cle266_set_primary_pll(struct via_pll_config config) { cle266_set_primary_pll_encoded(cle266_encode_pll(config)); } static void k800_set_primary_pll(struct via_pll_config config) { k800_set_primary_pll_encoded(k800_encode_pll(config)); } static void vx855_set_primary_pll(struct via_pll_config config) { k800_set_primary_pll_encoded(vx855_encode_pll(config)); } static void cle266_set_secondary_pll(struct via_pll_config config) { cle266_set_secondary_pll_encoded(cle266_encode_pll(config)); } static void k800_set_secondary_pll(struct via_pll_config config) { k800_set_secondary_pll_encoded(k800_encode_pll(config)); } static void vx855_set_secondary_pll(struct via_pll_config config) { k800_set_secondary_pll_encoded(vx855_encode_pll(config)); } static void k800_set_engine_pll(struct via_pll_config config) { set_engine_pll_encoded(k800_encode_pll(config)); } static void vx855_set_engine_pll(struct via_pll_config config) { set_engine_pll_encoded(vx855_encode_pll(config)); } static void set_primary_pll_state(u8 state) { u8 value; switch (state) { case VIA_STATE_ON: value = 0x20; break; case VIA_STATE_OFF: value = 0x00; break; default: return; } via_write_reg_mask(VIASR, 0x2D, value, 0x30); } static void set_secondary_pll_state(u8 state) { u8 value; switch (state) { case VIA_STATE_ON: value = 0x08; break; case VIA_STATE_OFF: value = 0x00; break; default: return; } via_write_reg_mask(VIASR, 0x2D, value, 0x0C); } static void set_engine_pll_state(u8 state) { u8 value; switch (state) { case VIA_STATE_ON: value = 0x02; break; case VIA_STATE_OFF: value = 0x00; break; default: return; } via_write_reg_mask(VIASR, 0x2D, value, 0x03); } static void set_primary_clock_state(u8 state) { u8 value; switch (state) { case VIA_STATE_ON: value = 0x20; break; case VIA_STATE_OFF: value = 0x00; break; default: return; } via_write_reg_mask(VIASR, 0x1B, value, 0x30); } static void set_secondary_clock_state(u8 state) { u8 value; switch (state) { case VIA_STATE_ON: value = 0x80; break; case VIA_STATE_OFF: value = 0x00; break; default: return; } via_write_reg_mask(VIASR, 0x1B, value, 0xC0); } static inline u8 set_clock_source_common(enum via_clksrc source, bool use_pll) { u8 data = 0; switch (source) { case VIA_CLKSRC_X1: data = 0x00; break; case VIA_CLKSRC_TVX1: data = 0x02; break; case VIA_CLKSRC_TVPLL: data = 0x04; /* 0x06 should be the same */ break; case VIA_CLKSRC_DVP1TVCLKR: data = 0x0A; break; case VIA_CLKSRC_CAP0: data = 0xC; break; case VIA_CLKSRC_CAP1: data = 0x0E; break; } if (!use_pll) data |= 1; return data; } static void set_primary_clock_source(enum via_clksrc source, bool use_pll) { u8 data = set_clock_source_common(source, use_pll) << 4; via_write_reg_mask(VIACR, 0x6C, data, 0xF0); } static void set_secondary_clock_source(enum via_clksrc source, bool use_pll) { u8 data = set_clock_source_common(source, use_pll); via_write_reg_mask(VIACR, 0x6C, data, 0x0F); } static void dummy_set_clock_state(u8 state) { printk(KERN_INFO "Using undocumented set clock state.\n%s", via_slap); } static void dummy_set_clock_source(enum via_clksrc source, bool use_pll) { printk(KERN_INFO "Using undocumented set clock source.\n%s", via_slap); } static void dummy_set_pll_state(u8 state) { printk(KERN_INFO "Using undocumented set PLL state.\n%s", via_slap); } static void dummy_set_pll(struct via_pll_config config) { printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap); } static void noop_set_clock_state(u8 state) { } void via_clock_init(struct via_clock *clock, int gfx_chip) { switch (gfx_chip) { case UNICHROME_CLE266: case UNICHROME_K400: clock->set_primary_clock_state = dummy_set_clock_state; clock->set_primary_clock_source = dummy_set_clock_source; clock->set_primary_pll_state = dummy_set_pll_state; clock->set_primary_pll = cle266_set_primary_pll; clock->set_secondary_clock_state = dummy_set_clock_state; clock->set_secondary_clock_source = dummy_set_clock_source; clock->set_secondary_pll_state = dummy_set_pll_state; clock->set_secondary_pll = cle266_set_secondary_pll; clock->set_engine_pll_state = dummy_set_pll_state; clock->set_engine_pll = dummy_set_pll; break; case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: case UNICHROME_CX700: case UNICHROME_CN750: case UNICHROME_K8M890: case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: clock->set_primary_clock_state = set_primary_clock_state; clock->set_primary_clock_source = set_primary_clock_source; clock->set_primary_pll_state = set_primary_pll_state; clock->set_primary_pll = k800_set_primary_pll; clock->set_secondary_clock_state = set_secondary_clock_state; clock->set_secondary_clock_source = set_secondary_clock_source; clock->set_secondary_pll_state = set_secondary_pll_state; clock->set_secondary_pll = k800_set_secondary_pll; clock->set_engine_pll_state = set_engine_pll_state; clock->set_engine_pll = k800_set_engine_pll; break; case UNICHROME_VX855: case UNICHROME_VX900: clock->set_primary_clock_state = set_primary_clock_state; clock->set_primary_clock_source = set_primary_clock_source; clock->set_primary_pll_state = set_primary_pll_state; clock->set_primary_pll = vx855_set_primary_pll; clock->set_secondary_clock_state = set_secondary_clock_state; clock->set_secondary_clock_source = set_secondary_clock_source; clock->set_secondary_pll_state = set_secondary_pll_state; clock->set_secondary_pll = vx855_set_secondary_pll; clock->set_engine_pll_state = set_engine_pll_state; clock->set_engine_pll = vx855_set_engine_pll; break; } if (machine_is_olpc()) { /* The OLPC XO-1.5 cannot suspend/resume reliably if the * IGA1/IGA2 clocks are set as on or off (memory rot * occasionally happens during suspend under such * configurations). * * The only known stable scenario is to leave this bits as-is, * which in their default states are documented to enable the * clock only when it is needed. */ clock->set_primary_clock_state = noop_set_clock_state; clock->set_secondary_clock_state = noop_set_clock_state; } } ckground. The gcc "optimization pass" is really just broken, but now the GCC trunk problem seems to have escaped out of just specially built daily images, so we need to work around it in mainline. - Linus ] Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> 2017-02-03module: unify absolute krctab definitions for 32-bit and 64-bitArd Biesheuvel1-7/+0 The previous patch introduced a separate inline asm version of the krcrctab declaration template for use with 64-bit architectures, which cannot refer to ELF symbols using 32-bit quantities. This declaration should be equivalent to the C one for 32-bit architectures, but just in case - unify them in a separate patch, which can simply be dropped if it turns out to break anything. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> 2017-02-03modversions: treat symbol CRCs as 32 bit quantitiesArd Biesheuvel3-12/+27 The modversion symbol CRCs are emitted as ELF symbols, which allows us to easily populate the kcrctab sections by relying on the linker to associate each kcrctab slot with the correct value. This has a couple of downsides: - Given that the CRCs are treated as memory addresses, we waste 4 bytes for each CRC on 64 bit architectures, - On architectures that support runtime relocation, a R_<arch>_RELATIVE relocation entry is emitted for each CRC value, which identifies it as a quantity that requires fixing up based on the actual runtime load offset of the kernel. This results in corrupted CRCs unless we explicitly undo the fixup (and this is currently being handled in the core module code) - Such runtime relocation entries take up 24 bytes of __init space each, resulting in a x8 overhead in [uncompressed] kernel size for CRCs. Switching to explicit 32 bit values on 64 bit architectures fixes most of these issues, given that 32 bit values are not treated as quantities that require fixing up based on the actual runtime load offset. Note that on some ELF64 architectures [such as PPC64], these 32-bit values are still emitted as [absolute] runtime relocatable quantities, even if the value resolves to a build time constant. Since relative relocations are always resolved at build time, this patch enables MODULE_REL_CRCS on powerpc when CONFIG_RELOCATABLE=y, which turns the absolute CRC references into relative references into .rodata where the actual CRC value is stored. So redefine all CRC fields and variables as u32, and redefine the __CRC_SYMBOL() macro for 64 bit builds to emit the CRC reference using inline assembler (which is necessary since 64-bit C code cannot use 32-bit types to hold memory addresses, even if they are ultimately resolved using values that do not exceed 0xffffffff). To avoid potential problems with legacy 32-bit architectures using legacy toolchains, the equivalent C definition of the kcrctab entry is retained for 32-bit architectures. Note that this mostly reverts commit d4703aefdbc8 ("module: handle ppc64 relocating kcrctabs when CONFIG_RELOCATABLE=y") Acked-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> 2017-02-02Merge branch 'perf-urgent-for-linus' of ↵Linus Torvalds1-3/+0 git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull perf fixes from Ingo Molnar: "Five kernel fixes: - an mmap tracing ABI fix for certain mappings - a use-after-free fix, found via KASAN - three CPU hotplug related x86 PMU driver fixes" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf/x86/intel/uncore: Make package handling more robust perf/x86/intel/uncore: Clean up hotplug conversion fallout perf/x86/intel/rapl: Make package handling more robust perf/core: Fix PERF_RECORD_MMAP2 prot/flags for anonymous memory perf/core: Fix use-after-free bug 2017-02-01Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/netLinus Torvalds4-19/+26 Pull networking fixes from David Miller: 1) Fix handling of interrupt status in stmmac driver. Just because we have masked the event from generating interrupts, doesn't mean the bit won't still be set in the interrupt status register. From Alexey Brodkin. 2) Fix DMA API debugging splats in gianfar driver, from Arseny Solokha. 3) Fix off-by-one error in __ip6_append_data(), from Vlad Yasevich. 4) cls_flow does not match on icmpv6 codes properly, from Simon Horman. 5) Initial MAC address can be set incorrectly in some scenerios, from Ivan Vecera. 6) Packet header pointer arithmetic fix in ip6_tnl_parse_tlv_end_lim(), from Dan Carpenter. 7) Fix divide by zero in __tcp_select_window(), from Eric Dumazet. 8) Fix crash in iwlwifi when unregistering thermal zone, from Jens Axboe. 9) Check for DMA mapping errors in starfire driver, from Alexey Khoroshilov. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (31 commits) tcp: fix 0 divide in __tcp_select_window() ipv6: pointer math error in ip6_tnl_parse_tlv_enc_lim() net: fix ndo_features_check/ndo_fix_features comment ordering net/sched: matchall: Fix configuration race be2net: fix initial MAC setting ipv6: fix flow labels when the traffic class is non-0 net: thunderx: avoid dereferencing xcv when NULL net/sched: cls_flower: Correct matching on ICMPv6 code ipv6: Paritially checksum full MTU frames net/mlx4_core: Avoid command timeouts during VF driver device shutdown gianfar: synchronize DMA API usage by free_skb_rx_queue w/ gfar_new_page net: ethtool: add support for 2500BaseT and 5000BaseT link modes can: bcm: fix hrtimer/tasklet termination in bcm op removal net: adaptec: starfire: add checks for dma mapping errors net: phy: micrel: KSZ8795 do not set SUPPORTED_[Asym_]Pause can: Fix kernel panic at security_sock_rcv_skb net: macb: Fix 64 bit addressing support for GEM stmmac: Discard masked flags in interrupt status register net/mlx5e: Check ets capability before ets query FW command net/mlx5e: Fix update of hash function/key via ethtool ... 2017-02-01Merge branch 'for-linus' of ↵Linus Torvalds1-0/+1 git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull fscache fixes from Al Viro. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: fscache: Fix dead object requeue fscache: Clear outstanding writes when disabling a cookie FS-Cache: Initialise stores_lock in netfs cookie 2017-02-01net: fix ndo_features_check/ndo_fix_features comment orderingDimitris Michailidis1-14/+15 Commit cdba756f5803a2 ("net: move ndo_features_check() close to ndo_start_xmit()") inadvertently moved the doc comment for .ndo_fix_features instead of .ndo_features_check. Fix the comment ordering. Fixes: cdba756f5803a2 ("net: move ndo_features_check() close to ndo_start_xmit()") Signed-off-by: Dimitris Michailidis <dmichail@google.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-01perf/x86/intel/uncore: Make package handling more robustThomas Gleixner1-2/+0 The package management code in uncore relies on package mapping being available before a CPU is started. This changed with: 9d85eb9119f4 ("x86/smpboot: Make logical package management more robust") because the ACPI/BIOS information turned out to be unreliable, but that left uncore in broken state. This was not noticed because on a regular boot all CPUs are online before uncore is initialized. Move the allocation to the CPU online callback and simplify the hotplug handling. At this point the package mapping is established and correct. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Sebastian Siewior <bigeasy@linutronix.de> Cc: Stephane Eranian <eranian@google.com> Cc: Vince Weaver <vincent.weaver@maine.edu> Cc: Yasuaki Ishimatsu <yasu.isimatu@gmail.com> Fixes: 9d85eb9119f4 ("x86/smpboot: Make logical package management more robust") Link: http://lkml.kernel.org/r/20170131230141.377156255@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>