From b9bb4f2ef029951bfa3e25df1a85b4af870d9f89 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Sat, 23 Jun 2007 17:16:30 -0700 Subject: [PATCH] --- yaml --- r: 57983 b: refs/heads/master c: 819062219abf8a78e54cad5c1c8716e6c8e7b870 h: refs/heads/master i: 57981: c9cfefd9b13bbab960a37adcb33958159dc3ab20 57979: 931d37617fe7bebe276b7a6eed65b43a77120a6e 57975: a2bb7c786f1e9e1ee498fd79ecc2c6e6ffa1d4d0 57967: c39259326e4396efa5319ee5ce0e0ee1d86a09f6 57951: 5d4c6c18a6553b6cfa6390b5b58e6f0d11e03bc7 57919: 1c3218545ce1fbfec4949a2e3158478182c07e5b 57855: 67805f9ec90563f68e9f09b1730acb228cb55abe v: v3 --- [refs] | 2 +- trunk/drivers/mfd/sm501.c | 33 ++++++++++++++++++++++++++++++-- trunk/include/linux/sm501-regs.h | 5 +++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index b28e1ac08d8d..fae382146d7e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5136237bc392413332b02e69ada158c307da658f +refs/heads/master: 819062219abf8a78e54cad5c1c8716e6c8e7b870 diff --git a/trunk/drivers/mfd/sm501.c b/trunk/drivers/mfd/sm501.c index 3a0ecfc404e9..e14d70e07418 100644 --- a/trunk/drivers/mfd/sm501.c +++ b/trunk/drivers/mfd/sm501.c @@ -855,6 +855,24 @@ static void sm501_init_regs(struct sm501_devdata *sm, dev_info(sm->dev, "setting MCLK to %ld\n", init->mclk); sm501_set_clock(sm->dev, SM501_CLOCK_MCLK, init->mclk); } + +} + +/* Check the PLL sources for the M1CLK and M1XCLK + * + * If the M1CLK and M1XCLKs are not sourced from the same PLL, then + * there is a risk (see errata AB-5) that the SM501 will cease proper + * function. If this happens, then it is likely the SM501 will + * hang the system. +*/ + +static int sm501_check_clocks(struct sm501_devdata *sm) +{ + unsigned long pwrmode = readl(sm->regs + SM501_CURRENT_CLOCK); + unsigned long msrc = (pwrmode & SM501_POWERMODE_M_SRC); + unsigned long m1src = (pwrmode & SM501_POWERMODE_M1_SRC); + + return ((msrc == 0 && m1src != 0) || (msrc != 0 && m1src == 0)); } static unsigned int sm501_mem_local[] = { @@ -911,6 +929,13 @@ static int sm501_init_dev(struct sm501_devdata *sm) } } + ret = sm501_check_clocks(sm); + if (ret) { + dev_err(sm->dev, "M1X and M clocks sourced from different " + "PLLs\n"); + return -EINVAL; + } + /* always create a framebuffer */ sm501_register_display(sm, &mem_avail); @@ -1048,8 +1073,12 @@ static struct sm501_initdata sm501_pci_initdata = { }, .devices = SM501_USE_ALL, - .mclk = 100 * MHZ, - .m1xclk = 160 * MHZ, + + /* Errata AB-3 says that 72MHz is the fastest available + * for 33MHZ PCI with proper bus-mastering operation */ + + .mclk = 72 * MHZ, + .m1xclk = 144 * MHZ, }; static struct sm501_platdata_fbsub sm501_pdata_fbsub = { diff --git a/trunk/include/linux/sm501-regs.h b/trunk/include/linux/sm501-regs.h index cc9be4a11861..8b4ecf02f9dc 100644 --- a/trunk/include/linux/sm501-regs.h +++ b/trunk/include/linux/sm501-regs.h @@ -64,6 +64,11 @@ #define SM501_DEBUG_CONTROL (0x000034) /* power management */ +#define SM501_POWERMODE_P2X_SRC (1<<29) +#define SM501_POWERMODE_V2X_SRC (1<<20) +#define SM501_POWERMODE_M_SRC (1<<12) +#define SM501_POWERMODE_M1_SRC (1<<4) + #define SM501_CURRENT_GATE (0x000038) #define SM501_CURRENT_CLOCK (0x00003C) #define SM501_POWER_MODE_0_GATE (0x000040)