* Re: [PATCH 1/2] kdump: Allow shrinking of kdump region to be overridden
From: Benjamin Herrenschmidt @ 2011-03-24 4:33 UTC (permalink / raw)
To: Eric W. Biederman
Cc: linuxppc-dev, Anton Blanchard, kexec, linux-kernel, WANG Cong
In-Reply-To: <im6fj2$576$1@dough.gmane.org>
On Mon, 2011-03-21 at 03:10 +0000, WANG Cong wrote:
> On Tue, 15 Mar 2011 22:22:19 +0530, Mahesh J Salgaonkar wrote:
> >> Okay, but with this patch applied, we will just ignore rtas region,
> >> right?
> > Correct.
> >> Thus, when I echo 0 to free all the 128M crashkernel memory, the final
> >> result will be 32M left, which means crash_size will still show 32M.
> >> This looks odd.
> >>
> >> How about skipping the 32M as a whole? I mean once the region being
> >> freed has overlap with this rtas region, skip the whole rtas region,
> >> and let crash_size
> >> show 0?
> > The existing code from crash_shrink_memory() function reduces the crash
> > size to 0 when echo'ed 0. I did test this patchset and verified that
> > /sys/kernel/kexec_crash_size show 0 value.
>
> Oh, ok.
>
> Acked-by: WANG Cong <xiyou.wangcong@gmail.com>
So Eric, what's the right approach to get that merged ? This is a bug
gating an important delivery for us, and the patch doesn't appear
terribly invasive ? :-)
I can send it to Linus myself if you prefer and give me your Ack.
Cheers,
Ben.
^ permalink raw reply
* Query: PCIe range entry at pcie@0 in dts files
From: Kushwaha Prabhakar-B32579 @ 2011-03-24 3:20 UTC (permalink / raw)
To: linuxppc-dev@lists.ozlabs.org
Hi all,
I have query about usage of range field at pcie@0 under PCIe controller. P=
lease find snap shot from mpc8536_36.dts..
pci3: pcie@fffe0b000 {
compatible =3D "fsl,mpc8548-pcie";
device_type =3D "pci";
#interrupt-cells =3D <1>;
#size-cells =3D <2>;
#address-cells =3D <3>;
reg =3D <0xf 0xffe0b000 0 0x1000>;
bus-range =3D <0 0xff>;
ranges =3D <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x20000000
0x01000000 0 0x00000000 0xf 0xffc30000 0 0x00010000>;
clock-frequency =3D <33333333>;
interrupt-parent =3D <&mpic>;
interrupts =3D <27 0x2>;
interrupt-map-mask =3D <0xf800 0 0 7>;
interrupt-map =3D <
/* IDSEL 0x0 */
0000 0 0 1 &mpic 8 1
0000 0 0 2 &mpic 9 1
0000 0 0 3 &mpic 10 1
0000 0 0 4 &mpic 11 1
>;
pcie@0 {
reg =3D <0 0 0 0 0>;
#size-cells =3D <2>;
#address-cells =3D <3>;
device_type =3D "pci";
ranges =3D <0x02000000 0 0xe0000000 --> child/port start address
0x02000000 0 0xe0000000 --> Parent bus address
0 0x20000000
0x01000000 0 0x00000000
0x01000000 0 0x00000000
0 0x00100000>;
};
};
Question:
A) is ranges filed of pcie@0 really required?
I just went through the code and found scan_OF_for_pci_dev() called from =
pci_busdev_to_OF_node() touches pcie@0 node. But, It does not even uses ran=
ge filed.=20
static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,=
unsigned int devfn) {
---
---
for_each_child_of_node(parent, np) {
reg =3D of_get_property(np, "reg", &psize);=20
=20
---
---
if (!strcmp(np->name, "multifunc-device")) {=20
=20
}
I also checked "Power_ePAPR_APPROVED_v1.0.pdf". It never say range filed=
required for child bus.
B) if range field of pcie@0 required. why does child/port start address sam=
e as Parent bus address? Range property provides mapping of port address t=
o parent address space.
So the value should be 0x00000000. Means port's address starting from 0x000=
00000 to size 0x20000000 is mapped parent's 0xe0000000.
ranges =3D <0x02000000 0 0x00000000 --> Child/port's start address
0x02000000 0 0xe0000000 --> Parent bus address
0 0x20000000
0x01000000 0 0x00000000
0x01000000 0 0x00000000
0 0x00100000>;
--Prabhakar
^ permalink raw reply
* Re: [PATCH V12 4/4] ptp: Added a clock driver for the National Semiconductor PHYTER.
From: John Stultz @ 2011-03-23 21:46 UTC (permalink / raw)
To: Richard Cochran
Cc: Rodolfo Giometti, Arnd Bergmann, Peter Zijlstra, linux-api,
devicetree-discuss, linux-kernel, Russell King, Paul Mackerras,
Thomas Gleixner, Alan Cox, netdev, Mike Frysinger,
Christoph Lameter, linuxppc-dev, David Miller, linux-arm-kernel,
Krzysztof Halasa
In-Reply-To: <f8af215ebe32a8c0f4b3a82b8ee7e8008b4feb1e.1298878618.git.richard.cochran@omicron.at>
On Mon, 2011-02-28 at 08:58 +0100, Richard Cochran wrote:
> This patch adds support for the PTP clock found on the DP83640.
> The basic clock operations and one external time stamp have
> been implemented.
Just locking rule comment nits here.
> +static int tdr_write(int bc, struct phy_device *dev,
> + const struct timespec *ts, u16 cmd)
> +{
> + ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_nsec & 0xffff);/* ns[15:0] */
> + ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_nsec >> 16); /* ns[31:16] */
> + ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_sec & 0xffff); /* sec[15:0] */
> + ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_sec >> 16); /* sec[31:16]*/
> +
> + ext_write(bc, dev, PAGE4, PTP_CTL, cmd);
> +
> + return 0;
> +}
The above needs to hold the extreg_lock, and should be commented as
such.
And again, the function names are sort of generic, and could use a
dp83640_ prefix or something.
thanks
-john
^ permalink raw reply
* Re: [PATCH V12 3/4] ptp: Added a clock driver for the IXP46x.
From: John Stultz @ 2011-03-23 21:43 UTC (permalink / raw)
To: Richard Cochran
Cc: Rodolfo Giometti, Arnd Bergmann, Peter Zijlstra, linux-api,
devicetree-discuss, linux-kernel, Russell King, Paul Mackerras,
Thomas Gleixner, Alan Cox, netdev, Mike Frysinger,
Christoph Lameter, linuxppc-dev, David Miller, linux-arm-kernel,
Krzysztof Halasa
In-Reply-To: <cd6ddff0dcca60ac88b35660505d7bf54ad32405.1298878618.git.richard.cochran@omicron.at>
On Mon, 2011-02-28 at 08:58 +0100, Richard Cochran wrote:
> This patch adds a driver for the hardware time stamping unit found on the
> IXP465. The basic clock operations and an external trigger are implemented.
>
> Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
> Acked-by: John Stultz <johnstul@us.ibm.com>
My ack is still fine, but found a few more nits to consider on another
pass...
> +static int match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seq)
[snip]
> +static void do_rx_timestamp(struct port *port, struct sk_buff *skb)
[snip]
> +static u64 sys_time_read(struct ixp46x_ts_regs *regs)
[snip]
> +static void sys_time_write(struct ixp46x_ts_regs *regs, u64 ns)
I know these are static, but these function names are sort of generic
names, and make grep/cscoping for similar sounding functions a little
noisy.
Maybe add a ipx_ prefix just to be more obvious?
thanks
-john
^ permalink raw reply
* Re: [PATCH V12 2/4] ptp: Added a clock that uses the eTSEC found on the MPC85xx.
From: John Stultz @ 2011-03-23 21:30 UTC (permalink / raw)
To: Richard Cochran
Cc: Rodolfo Giometti, Arnd Bergmann, Peter Zijlstra, linux-api,
devicetree-discuss, linux-kernel, Russell King, Paul Mackerras,
Thomas Gleixner, Alan Cox, netdev, Mike Frysinger,
Christoph Lameter, linuxppc-dev, David Miller, linux-arm-kernel,
Krzysztof Halasa
In-Reply-To: <aa97e94c82ebd8953d83b53f64cbfef66c81b7be.1298878618.git.richard.cochran@omicron.at>
On Mon, 2011-02-28 at 08:57 +0100, Richard Cochran wrote:
> The eTSEC includes a PTP clock with quite a few features. This patch adds
> support for the basic clock adjustment functions, plus two external time
> stamps, one alarm, and the PPS callback.
Just a minor question on the locking, but otherwise looks ok.
> --- /dev/null
> +++ b/drivers/net/gianfar_ptp.c
> @@ -0,0 +1,579 @@
[snip]
> +/*
> + * Register access functions
> + */
So what are the locking rules on the functions below? I assume the
etsects->lock needs to be held prior to calling, so that should be made
explicit in a comment.
> +static u64 tmr_cnt_read(struct etsects *etsects)
> +{
> + u64 ns;
> + u32 lo, hi;
> +
> + lo = gfar_read(&etsects->regs->tmr_cnt_l);
> + hi = gfar_read(&etsects->regs->tmr_cnt_h);
> + ns = ((u64) hi) << 32;
> + ns |= lo;
> + return ns;
> +}
> +
> +static void tmr_cnt_write(struct etsects *etsects, u64 ns)
> +{
> + u32 hi = ns >> 32;
> + u32 lo = ns & 0xffffffff;
> +
> + gfar_write(&etsects->regs->tmr_cnt_l, lo);
> + gfar_write(&etsects->regs->tmr_cnt_h, hi);
> +}
> +
> +static void set_alarm(struct etsects *etsects)
> +{
> + u64 ns;
> + u32 lo, hi;
> +
> + ns = tmr_cnt_read(etsects) + 1500000000ULL;
> + ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
> + ns -= etsects->tclk_period;
> + hi = ns >> 32;
> + lo = ns & 0xffffffff;
> + gfar_write(&etsects->regs->tmr_alarm1_l, lo);
> + gfar_write(&etsects->regs->tmr_alarm1_h, hi);
> +}
> +
> +static void set_fipers(struct etsects *etsects)
> +{
> + u32 tmr_ctrl = gfar_read(&etsects->regs->tmr_ctrl);
> +
> + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl & (~TE));
> + gfar_write(&etsects->regs->tmr_prsc, etsects->tmr_prsc);
> + gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1);
> + gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2);
> + set_alarm(etsects);
> + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|TE);
> +}
> +
[snip]
> +static int gianfar_ptp_probe(struct platform_device *dev)
> +{
> + struct device_node *node = dev->dev.of_node;
> + struct etsects *etsects;
> + struct timespec now;
> + int err = -ENOMEM;
> + u32 tmr_ctrl;
> +
> + etsects = kzalloc(sizeof(*etsects), GFP_KERNEL);
> + if (!etsects)
> + goto no_memory;
> +
> + err = -ENODEV;
> +
> + etsects->caps = ptp_gianfar_caps;
> + etsects->cksel = DEFAULT_CKSEL;
> +
> + if (get_of_u32(node, "fsl,tclk-period", &etsects->tclk_period) ||
> + get_of_u32(node, "fsl,tmr-prsc", &etsects->tmr_prsc) ||
> + get_of_u32(node, "fsl,tmr-add", &etsects->tmr_add) ||
> + get_of_u32(node, "fsl,tmr-fiper1", &etsects->tmr_fiper1) ||
> + get_of_u32(node, "fsl,tmr-fiper2", &etsects->tmr_fiper2) ||
> + get_of_u32(node, "fsl,max-adj", &etsects->caps.max_adj)) {
> + pr_err("device tree node missing required elements\n");
> + goto no_node;
> + }
> +
> + etsects->irq = platform_get_irq(dev, 0);
> +
> + if (etsects->irq == NO_IRQ) {
> + pr_err("irq not in device tree\n");
> + goto no_node;
> + }
> + if (request_irq(etsects->irq, isr, 0, DRIVER, etsects)) {
> + pr_err("request_irq failed\n");
> + goto no_node;
> + }
> +
> + etsects->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0);
> + if (!etsects->rsrc) {
> + pr_err("no resource\n");
> + goto no_resource;
> + }
> + if (request_resource(&ioport_resource, etsects->rsrc)) {
> + pr_err("resource busy\n");
> + goto no_resource;
> + }
> +
> + spin_lock_init(&etsects->lock);
> +
> + etsects->regs = ioremap(etsects->rsrc->start,
> + 1 + etsects->rsrc->end - etsects->rsrc->start);
> + if (!etsects->regs) {
> + pr_err("ioremap ptp registers failed\n");
> + goto no_ioremap;
> + }
> + getnstimeofday(&now);
> + ptp_gianfar_settime(&etsects->caps, &now);
> +
> + tmr_ctrl =
> + (etsects->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT |
> + (etsects->cksel & CKSEL_MASK) << CKSEL_SHIFT;
> +
> + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl);
> + gfar_write(&etsects->regs->tmr_add, etsects->tmr_add);
> + gfar_write(&etsects->regs->tmr_prsc, etsects->tmr_prsc);
> + gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1);
> + gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2);
> + set_alarm(etsects);
> + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE);
Does any of the above need a lock should an irq land in the middle of
the writes?
thanks
-john
^ permalink raw reply
* Re: [PATCH V12 1/4] ptp: Added a brand new class driver for ptp clocks.
From: John Stultz @ 2011-03-23 21:19 UTC (permalink / raw)
To: Richard Cochran
Cc: Rodolfo Giometti, Arnd Bergmann, Peter Zijlstra, linux-api,
devicetree-discuss, linux-kernel, Russell King, Paul Mackerras,
Thomas Gleixner, Alan Cox, netdev, Mike Frysinger,
Christoph Lameter, linuxppc-dev, David Miller, linux-arm-kernel,
Krzysztof Halasa
In-Reply-To: <bf964489f4c6ee51bd8a2ab818cd6a5e2f544627.1298878618.git.richard.cochran@omicron.at>
On Mon, 2011-02-28 at 08:57 +0100, Richard Cochran wrote:
> This patch adds an infrastructure for hardware clocks that implement
> IEEE 1588, the Precision Time Protocol (PTP). A class driver offers a
> registration method to particular hardware clock drivers. Each clock is
> presented as a standard POSIX clock.
>
> The ancillary clock features are exposed in two different ways, via
> the sysfs and by a character device.
>
> Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
I think this looks mostly ok. I've got one concern on the locking and
there are a few minor nits that might need extra commenting below.
thanks
-john
> --- /dev/null
> +++ b/Documentation/ptp/testptp.c
[snip]
> + if (0x7fffffff != adjfreq) {
> + memset(&tx, 0, sizeof(tx));
> + tx.modes = ADJ_FREQUENCY;
> + tx.freq = (long) (adjfreq * 65.536);
So, 65.536... I understand you're converting ppb to ppm << 16 (which is
what adjtime takes), but I'm not sure if anyone else will. I'd either
wrap that in a commented conversion function/macro or just do the
conversion explicitly (freq = (adjfreq << 16)/1000; although this has
potential overflow risks with large ppb values) with a comment about
what is going on.
> --- /dev/null
> +++ b/drivers/ptp/ptp_clock.c
> @@ -0,0 +1,320 @@
[snip]
> +static void enqueue_external_timestamp(struct timestamp_event_queue *queue,
> + struct ptp_clock_event *src)
> +{
> + struct ptp_extts_event *dst;
> + unsigned long flags;
> + u32 remainder;
> +
> + dst = &queue->buf[queue->tail];
Doesn't the lock need to happen before you access the
queue->buf[queue->tail] ?
For example: What happens if two cpus enter the function at the same
time, both get the same tail index, one overwrite the other's data, then
both take turns bumping up the tail pointer?
> + dst->index = src->index;
> + dst->t.sec = div_u64_rem(src->timestamp, 1000000000, &remainder);
> + dst->t.nsec = remainder;
> +
> + spin_lock_irqsave(&queue->lock, flags);
> +
> + if (!queue_free(queue))
> + queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS;
> +
> + queue->tail = (queue->tail + 1) % PTP_MAX_TIMESTAMPS;
> +
> + spin_unlock_irqrestore(&queue->lock, flags);
> +}
[snip]
> +static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
> +{
> + struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
> + struct ptp_clock_info *ops;
> + int err = -EOPNOTSUPP;
> +
> + ops = ptp->info;
> +
> + if (tx->modes & ADJ_SETOFFSET) {
> + struct timespec ts;
> + ktime_t kt;
> + s64 delta;
> +
> + ts.tv_sec = tx->time.tv_sec;
> + ts.tv_nsec = tx->time.tv_usec;
> +
> + if (!(tx->modes & ADJ_NANO))
> + ts.tv_nsec *= 1000;
> +
> + if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC)
> + return -EINVAL;
> +
> + kt = timespec_to_ktime(ts);
> + delta = ktime_to_ns(kt);
> + err = ops->adjtime(ops, delta);
> +
> + } else if (tx->modes & ADJ_FREQUENCY) {
> + s64 ppb = 1 + tx->freq;
> + ppb *= 125;
> + ppb >>= 13;
((1 + freq) *125)>>13 == magic :)
Needs a clear comment.
> + err = ops->adjfreq(ops, (s32)ppb);
> + }
> +
> + return err;
> +}
[snip]
> diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
> new file mode 100644
> index 0000000..2f76266
> --- /dev/null
> +++ b/drivers/ptp/ptp_private.h
> @@ -0,0 +1,86 @@
> +/*
> + * PTP 1588 clock support - private declarations for the core module.
> + *
> + * Copyright (C) 2010 OMICRON electronics GmbH
> + *
> + * 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 of the License, or
> + * (at your option) any later version.
> + *
> + * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +#ifndef _PTP_PRIVATE_H_
> +#define _PTP_PRIVATE_H_
> +
> +#include <linux/cdev.h>
> +#include <linux/device.h>
> +#include <linux/mutex.h>
> +#include <linux/posix-clock.h>
> +#include <linux/ptp_clock.h>
> +#include <linux/ptp_clock_kernel.h>
> +#include <linux/time.h>
> +
> +#define PTP_MAX_TIMESTAMPS 128
> +#define PTP_BUF_TIMESTAMPS 30
> +
> +struct timestamp_event_queue {
> + struct ptp_extts_event buf[PTP_MAX_TIMESTAMPS];
> + int head;
> + int tail;
> + spinlock_t lock;
> +};
> +
> +struct ptp_clock {
> + struct posix_clock clock;
> + struct device *dev;
> + struct ptp_clock_info *info;
> + dev_t devid;
> + int index; /* index into clocks.map */
> + struct pps_device *pps_source;
> + struct timestamp_event_queue tsevq; /* simple fifo for time stamps */
> + struct mutex tsevq_mux; /* one process at a time reading the fifo */
> + wait_queue_head_t tsev_wq;
> +};
> +
> +static inline int queue_cnt(struct timestamp_event_queue *q)
> +{
> + int cnt = q->tail - q->head;
> + return cnt < 0 ? PTP_MAX_TIMESTAMPS + cnt : cnt;
> +}
q->tail and head access probably need to happen only when locked.
So probably need a comment that queue_cnt must be called only when
holding the proper lock.
thanks
-john
^ permalink raw reply
* mpc8250 kernel booting
From: suresh chandra @ 2011-03-23 20:44 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1.1: Type: text/plain, Size: 701 bytes --]
Hi All,
I am having a strange serial console issue while booting Linux 2.6.38 and
Linux 2.6.34.8
We are using customized board based on MPC8250 , Console on SCC 1 and root
file system on ramdisk.
We are using U-boot for loading Linux.
Soon after u-boot handles control over to kernel, nothing comes on serial
port until I hit <ENTER> key
Then once again kernel pauses at "NET:Registered protocol family 17" and
proceeds after hitting <ENTER> key.
One more time Kernel pauses at "Freeing unused kernel memory: 156k init"
until I hit <ENTER> key.
I attached serial capture for your reference.
I want my board to boot with out user intervention. Please help me in
finding a solution.
Thanks,
Suresh
[-- Attachment #1.2: Type: text/html, Size: 798 bytes --]
[-- Attachment #2: capture1.txt --]
[-- Type: text/plain, Size: 4815 bytes --]
U-Boot 2008.10 (Mar 22 2011 - 03:29:50)
MPC8250 Reset Status: External Soft, External Hard
MPC8250 Clock Configuration
- Bus-to-Core Mult 4x, VCO Div 2, 60x Bus Freq 25-75 , Core Freq 100-300
- dfbrg 0, corecnf 0x1a, busdf 3, cpmdf 1, plldf 0, pllmf 1, pcidf 3
- vco_out 266666664, scc_clk 66666666, brg_clk 66666666
- cpu_clk 266666664, cpm_clk 133333332, bus_clk 66666666
CPU: MPC8250 (HiP4 Rev 14, Mask C.0 5K25A) at 266.667 MHz
Board: Cornet IPGATE
DRAM: (60x:10COL) 128 MB
FLASH: 256 MB
In: serial
Out: serial
Err: serial
Net: FCC1 ETHERNET, FCC2 ETHERNET
Press any key to interrupt autoboot: 2 \b\b\b 1 \b\b\b 0
IPGATE=> boot
Using FCC1 ETHERNET device
TFTP from server 192.168.235.60; our IP address is 192.168.235.22
Filename 'uImage'.
Load address: 0x1000000
Loading: *\b#################################################################
###########################################
done
Bytes transferred = 1581380 (182144 hex)
Using FCC1 ETHERNET device
TFTP from server 192.168.235.60; our IP address is 192.168.235.22
Filename 'test'.
Load address: 0x2000000
Loading: *\b#################################################################
#################################################################
#################
done
Bytes transferred = 2148495 (20c88f hex)
Using FCC1 ETHERNET device
TFTP from server 192.168.235.60; our IP address is 192.168.235.22
Filename 'dtb'.
Load address: 0x3000000
Loading: *\b##
done
Bytes transferred = 20000 (4e20 hex)
## Booting kernel from Legacy Image at 01000000 ...
Image Name: Linux-2.6.34.8
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 1581316 Bytes = 1.5 MB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at 02000000 ...
Image Name: RAMDISK Image
Image Type: PowerPC Linux RAMDisk Image (gzip compressed)
Data Size: 2148431 Bytes = 2 MB
Load Address: 05000000
Entry Point: 05000000
Verifying Checksum ... OK
## Flattened Device Tree blob at 03000000
Booting using the fdt blob at 0x3000000
Uncompressing Kernel Image ... OK
Loading Ramdisk to 07d95000, end 07fa184f ... OK
Loading Device Tree to 007f8000, end 007ffe1f ... OK
<Have to press <ENTER> Serial console>
console [ttyCPM0] enabled, bootconsole disabled
\rMount-cache hash table entries: 512
\rNET: Registered protocol family 16
\rbio: create slab <bio-0> at 0
\rSwitching to clocksource timebase
\rNET: Registered protocol family 2
\rIP route cache hash table entries: 1024 (order: 0, 4096 bytes)
\rTCP established hash table entries: 4096 (order: 3, 32768 bytes)
\rTCP bind hash table entries: 4096 (order: 2, 16384 bytes)
\rTCP: Hash tables configured (established 4096 bind 4096)
\rTCP reno registered
\rUDP hash table entries: 256 (order: 0, 4096 bytes)
\rUDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
\rNET: Registered protocol family 1
\rRPC: Registered udp transport module.
\rRPC: Registered tcp transport module.
\rRPC: Registered tcp NFSv4.1 backchannel transport module.
\rTrying to unpack rootfs image as initramfs...
\rrootfs image is not initramfs (no cpio magic); looks like an initrd
\rFreeing initrd memory: 2098k freed
\rInstalling knfsd (copyright (C) 1996 okir@monad.swb.de).
\rmsgmni has been set to 247
\ralg: No test for stdrng (krng)
\rBlock layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
\rio scheduler noop registered
\rio scheduler deadline registered
\rio scheduler cfq registered (default)
\rf011a00.serial: ttyCPM0 at MMIO 0xc9008a00 (irq = 40) is a CPM UART
\rf011a20.serial: ttyCPM1 at MMIO 0xc900ca20 (irq = 41) is a CPM UART
\rf011a40.serial: ttyCPM2 at MMIO 0xc9014a40 (irq = 42) is a CPM UART
\rf011a60.serial: ttyCPM3 at MMIO 0xc901ca60 (irq = 43) is a CPM UART
\rf011a80.serial: ttyCPM4 at MMIO 0xc9024a80 (irq = 16) is a CPM UART
\rf011a90.serial: ttyCPM5 at MMIO 0xc902ca90 (irq = 17) is a CPM UART
\rbrd: module loaded
\rloop: module loaded
\rnbd: registered device at major 43
\rPPP generic driver version 2.4.2
\rPPP Deflate Compression module registered
\rtun: Universal TUN/TAP device driver, 1.6
\rtun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
\reth0: fs_enet: 08:00:08:15:ca:fe
\reth1: fs_enet: 08:00:08:15:ca:ce
\rCPM2 Bitbanged MII: probed
\rCPM2 Bitbanged MII: probed
\rmice: PS/2 mouse device common for all mice
\rTCP cubic registered
\rNET: Registered protocol family 10
\rIPv6 over IPv4 tunneling driver
\rNET: Registered protocol family 17
<Have to press <ENTER> Serial console>
\rRAMDISK: gzip image found at block 0
VFS: Mounted root (ext2 filesystem) on device 1:0.
\rFreeing unused kernel memory: 156k init
<Have to press <ENTER> Serial console>
ADDRCONF(NETDEV_UP): eth0: link is not ready
\r~ #
~ #
~ #
~ # ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
^ permalink raw reply
* Re: [PATCH] crypto: caam - de-CHIP-ify device tree compatibles
From: Herbert Xu @ 2011-03-23 13:24 UTC (permalink / raw)
To: Grant Likely
Cc: Steve Cornelius, devicetree-discuss, linux-crypto, Scott Wood,
linuxppc-dev, Kumar Gala
In-Reply-To: <20110316005951.GA18791@angua.secretlab.ca>
On Tue, Mar 15, 2011 at 06:59:51PM -0600, Grant Likely wrote:
> On Tue, Mar 15, 2011 at 04:52:20PM -0500, Kim Phillips wrote:
> > - all the integration parameters have been captured by the binding.
> > - the block name really uniquely identifies this hardware.
> >
> > Some advocate putting SoC names everywhere in case software needs
> > to work around some chip-specific bug, but more precise SoC
> > information already exists in SVR, and board information already
> > exists in the top-level device tree node.
> >
> > Note that sometimes the SoC name is a worse identifier than the
> > block version, as the block version can change between revisions
> > of the same SoC.
> >
> > As a matter of historical reference, neither SEC versions 2.x
> > nor 3.x (driven by talitos) ever needed CHIP references.
> >
> > Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
>
> <sigh> Very well. As long as some level of versioning is used on the
> compatible values, I guess I can live with it.
>
> Acked-off-by: Grant Likely <grant.likely@secretlab.ca>
Patch applied. Thanks!
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH] crypto: caam - standardize device tree naming convention to utilize '-vX.Y'
From: Herbert Xu @ 2011-03-23 13:18 UTC (permalink / raw)
To: Kim Phillips
Cc: Kumar Gala, devicetree-discuss, linuxppc-dev, linux-crypto,
Steve Cornelius
In-Reply-To: <20110314174247.e5515448.kim.phillips@freescale.com>
On Mon, Mar 14, 2011 at 05:42:47PM -0500, Kim Phillips wrote:
> Help clarify that the number trailing in compatible nomenclature
> is the version number of the device, i.e., change:
>
> "fsl,p4080-sec4.0", "fsl,sec4.0";
>
> to:
>
> "fsl,p4080-sec-v4.0", "fsl,sec-v4.0";
>
> Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
> Cc: Kumar Gala <kumar.gala@freescale.com>
> Cc: Steve Cornelius <sec@pobox.com>
Applied.
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* (no subject)
From: segher @ 2011-03-23 7:41 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 705 bytes --]
Your message was not delivered due to the following reason:
Your message could not be delivered because the destination server was
not reachable within the allowed queue period. The amount of time
a message is queued before it is returned depends on local configura-
tion parameters.
Most likely there is a network problem that prevented delivery, but
it is also possible that the computer is turned off, or does not
have a mail system running right now.
Your message was not delivered within 5 days:
Host 135.67.214.12 is not responding.
The following recipients did not receive this message:
<linuxppc-dev@ozlabs.org>
Please reply to postmaster@ozlabs.org
if you feel this message to be in error.
[-- Attachment #2: attachment.zip --]
[-- Type: application/octet-stream, Size: 49726 bytes --]
^ permalink raw reply
* Re: mmotm threatens ppc preemption again
From: Jeremy Fitzhardinge @ 2011-03-22 13:34 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev, Andrew Morton, Hugh Dickins, Peter Zijlstra
In-Reply-To: <1300747942.2402.262.camel@pasglop>
On 03/21/2011 10:52 PM, Benjamin Herrenschmidt wrote:
> On Mon, 2011-03-21 at 11:24 +0000, Jeremy Fitzhardinge wrote:
>> I'm very sorry about that, I didn't realize power was also using that
>> interface. Unfortunately, the "no preemption" definition was an error,
>> and had to be changed to match the pre-existing locking rules.
>>
>> Could you implement a similar "flush batched pte updates on context
>> switch" as x86?
> Well, we already do that for -rt & co.
>
> However, we have another issue which is the reason we used those
> lazy_mmu hooks to do our flushing.
>
> Our PTEs eventually get faulted into a hash table which is what the real
> MMU uses. We must never (ever) allow that hash table to contain a
> duplicate entry for a given virtual address.
>
> When we do a batch, we remove things from the linux PTE, and keep a
> reference in our batch structure, and only update the hash table at the
> end of the batch.
Wouldn't implicitly ending a batch on context switch get the same effect?
> That means that we must not allow a hash fault to populate the hash with
> a "new" PTE value prior to the old one having been flushed out (which is
> possible if they different in protection attributes for example). For
> that to happen, we must basically not allow a page fault to re-populate
> a PTE invalidated by a batch before that batch has completed.
Kernel ptes are not generally populated on fault though, unless there's
something in power? On x86 it can happen when syncing a process's
kernel pmd with the init_mm one, but that shouldn't happen in the middle
of an update since you'd deadlock anyway. If a particular kernel
subsystem has its own locks to manage the ptes for a kernel mapping,
then that should prevent any nested updates within a batch shouldn't it?
> That translates to batches must only happen within a PTE lock section.
Well, in that case, I guess your best bet is to disable batching for
kernel pagetable updates. These apply_to_page_range() changes are the
first time any attempt to batch kernel pagetable updates has been made
(otherwise you would have seen this problem earlier), so not batching
them will not be a regression for you.
But I'm not sure what the proper fix to get batching in your case will
be. But the assumption that there's a pte lock for kernel ptes is not
valid.
J
^ permalink raw reply
* Re: [PATCH v6 0/6] powerpc, 52xx: add charon board support
From: Grant Likely @ 2011-03-22 20:58 UTC (permalink / raw)
To: Heiko Schocher
Cc: linux-fbdev, devicetree-discuss, Samuel Ortiz, Vincent Sanders,
linux-kernel, Ben Dooks, Randy Dunlap, Paul Mundt, linuxppc-dev,
Wolfgang Denk
In-Reply-To: <1300782452-528-1-git-send-email-hs@denx.de>
On Tue, Mar 22, 2011 at 2:27 AM, Heiko Schocher <hs@denx.de> wrote:
> cc: Wolfram Sang <w.sang@pengutronix.de>
> cc: Grant Likely <grant.likely@secretlab.ca>
> cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> cc: linux-fbdev@vger.kernel.org
> cc: devicetree-discuss@ozlabs.org
> cc: Ben Dooks <ben@simtec.co.uk>
> cc: Vincent Sanders <vince@simtec.co.uk>
> cc: Samuel Ortiz <sameo@linux.intel.com>
> cc: linux-kernel@vger.kernel.org
> cc: Randy Dunlap <rdunlap@xenotime.net>
> cc: Wolfgang Denk <wd@denx.de>
> cc: Paul Mundt <lethal@linux-sh.org>
>
> changes since v5:
> - repost complete patchseries, as Paul Mundt suggested
> - rebased against current head
> - add Acked-by from Samuel Ortiz (MFD parts)
> =A0http://www.spinics.net/lists/linux-fbdev/msg02550.html
> =A0http://linux.derkeiler.com/Mailing-Lists/Kernel/2011-01/msg11798.html
>
> =A0and Benjamin Herrenschmidt (DTS parts)
> =A0http://lists.ozlabs.org/pipermail/linuxppc-dev/2011-February/088279.ht=
ml
> - removed patch
> =A0"powerpc, mpc5200: update mpc5200_defconfig to fit for charon board."
> =A0therefore added
> =A0"powerpc, tqm5200: update tqm5200_defconfig to fit for charon board."
Why? As Wolfram mentioned, I'd rather see mpc5200 defconfig used.
Eventually I'd like to remove tqm5200_defconfig
I'll look through the rest of the patches soon.
g.
^ permalink raw reply
* Re: [PATCH 3/3, v2] fs_enet: Add PHY interface selection for MPC5121 fs_enet.
From: vooon341 @ 2011-03-22 14:10 UTC (permalink / raw)
To: linuxppc-dev; +Cc: netdev, linux-kernel, Vitaly Bordug
Add PHY interface selection for MPC5121 fs_enet.
Adds phy-connection-type optional property for ethernet node.
It should be rmii or mii.
Signed-off-by: Vladimir Ermakov <vooon341@gmail.com>
---
v2:
- replace Kconfig to device tree
- add phy-connection-type for mpc5121-fec nodes
---
drivers/net/fs_enet/fec.h | 6 ++++--
drivers/net/fs_enet/fs_enet-main.c | 14 ++++++++++++--
drivers/net/fs_enet/mac-fec.c | 9 ++++++---
3 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/drivers/net/fs_enet/fec.h b/drivers/net/fs_enet/fec.h
index e980527..9fd1ff5 100644
--- a/drivers/net/fs_enet/fec.h
+++ b/drivers/net/fs_enet/fec.h
@@ -23,6 +23,10 @@
#define FEC_ECNTRL_ETHER_EN 0x00000002
#define FEC_ECNTRL_RESET 0x00000001
+/* RMII mode enabled only when MII_MODE bit is set too. */
+#define FEC_RCNTRL_RMII_MODE (0x00000100 | \
+ FEC_RCNTRL_MII_MODE | FEC_RCNTRL_FCE)
+#define FEC_RCNTRL_FCE 0x00000020
#define FEC_RCNTRL_BC_REJ 0x00000010
#define FEC_RCNTRL_PROM 0x00000008
#define FEC_RCNTRL_MII_MODE 0x00000004
@@ -33,8 +37,6 @@
#define FEC_TCNTRL_HBC 0x00000002
#define FEC_TCNTRL_GTS 0x00000001
-
-
/*
* Delay to wait for FEC reset command to complete (in us)
*/
diff --git a/drivers/net/fs_enet/fs_enet-main.c
b/drivers/net/fs_enet/fs_enet-main.c
index 24cb953..c424159 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -788,16 +788,20 @@ static int fs_init_phy(struct net_device *dev)
{
struct fs_enet_private *fep = netdev_priv(dev);
struct phy_device *phydev;
+ phy_interface_t iface;
fep->oldlink = 0;
fep->oldspeed = 0;
fep->oldduplex = -1;
+ iface = (fep->fpi->use_rmii) ?
+ PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII;
+
phydev = of_phy_connect(dev, fep->fpi->phy_node, &fs_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ iface);
if (!phydev) {
phydev = of_phy_connect_fixed_link(dev, &fs_adjust_link,
- PHY_INTERFACE_MODE_MII);
+ iface);
}
if (!phydev) {
dev_err(&dev->dev, "Could not attach to PHY\n");
@@ -1005,6 +1009,7 @@ static int __devinit fs_enet_probe(struct
platform_device *ofdev)
struct fs_platform_info *fpi;
const u32 *data;
const u8 *mac_addr;
+ char *phy_connection_type;
int privsize, len, ret = -ENODEV;
if (!ofdev->dev.of_match)
@@ -1032,6 +1037,11 @@ static int __devinit fs_enet_probe(struct
platform_device *ofdev)
NULL)))
goto out_free_fpi;
+ phy_connection_type = of_get_property(ofdev->dev.of_node,
+ "phy-connection-type", NULL);
+ if (phy_connection_type && strcmp("rmii", phy_connection_type) == 0)
+ fpi->use_rmii = 1;
+
privsize = sizeof(*fep) +
sizeof(struct sk_buff **) *
(fpi->rx_ring + fpi->tx_ring);
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 61035fc..7ba36c1 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -322,10 +322,11 @@ static void restart(struct net_device *dev)
FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
#else
/*
- * Only set MII mode - do not touch maximum frame length
+ * Only set MII/RMII mode - do not touch maximum frame length
* configured before.
*/
- FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE);
+ FS(fecp, r_cntrl, (fpi->use_rmii) ?
+ FEC_RCNTRL_RMII_MODE : FEC_RCNTRL_MII_MODE);
#endif
/*
* adjust to duplex mode
@@ -381,7 +382,9 @@ static void stop(struct net_device *dev)
/* shut down FEC1? that's where the mii bus is */
if (fpi->has_phy) {
- FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
+ FS(fecp, r_cntrl, (fpi->use_rmii) ?
+ FEC_RCNTRL_RMII_MODE :
+ FEC_RCNTRL_MII_MODE); /* MII/RMII enable */
FS(fecp, ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
FW(fecp, ievent, FEC_ENET_MII);
FW(fecp, mii_speed, feci->mii_speed);
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 2/3,v2] serial: Add PSC UART support for MPC5125 SoC
From: vooon341 @ 2011-03-22 14:07 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Anatolij Gustschin, linux-kernel
Adds PSC UART support for MPC5125 SoC.
MPC5125 has different register map than in MPC5121.
Signed-off-by: Vladimir Ermakov <vooon341@gmail.com>
---
v2:
- Replace hack with replacing struct mpc52xx_psc to proper code.
---
arch/powerpc/include/asm/mpc52xx_psc.h | 49 ++++
drivers/tty/serial/mpc52xx_uart.c | 406 ++++++++++++++++++++++++++++----
2 files changed, 414 insertions(+), 41 deletions(-)
diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h
b/arch/powerpc/include/asm/mpc52xx_psc.h
index 2966df6..d0ece25 100644
--- a/arch/powerpc/include/asm/mpc52xx_psc.h
+++ b/arch/powerpc/include/asm/mpc52xx_psc.h
@@ -299,4 +299,53 @@ struct mpc512x_psc_fifo {
#define rxdata_32 rxdata.rxdata_32
};
+struct mpc5125_psc {
+ u8 mr1; /* PSC + 0x00 */
+ u8 reserved0[3];
+ u8 mr2; /* PSC + 0x04 */
+ u8 reserved1[3];
+ struct {
+ u16 status; /* PSC + 0x08 */
+ u8 reserved2[2];
+ u8 clock_select; /* PSC + 0x0c */
+ u8 reserved3[3];
+ } sr_csr;
+ u8 command; /* PSC + 0x10 */
+ u8 reserved4[3];
+ union { /* PSC + 0x14 */
+ u8 buffer_8;
+ u16 buffer_16;
+ u32 buffer_32;
+ } buffer;
+ struct {
+ u8 ipcr; /* PSC + 0x18 */
+ u8 reserved5[3];
+ u8 acr; /* PSC + 0x1c */
+ u8 reserved6[3];
+ } ipcr_acr;
+ struct {
+ u16 isr; /* PSC + 0x20 */
+ u8 reserved7[2];
+ u16 imr; /* PSC + 0x24 */
+ u8 reserved8[2];
+ } isr_imr;
+ u8 ctur; /* PSC + 0x28 */
+ u8 reserved9[3];
+ u8 ctlr; /* PSC + 0x2c */
+ u8 reserved10[3];
+ u32 ccr; /* PSC + 0x30 */
+ u32 ac97slots; /* PSC + 0x34 */
+ u32 ac97cmd; /* PSC + 0x38 */
+ u32 ac97data; /* PSC + 0x3c */
+ u8 reserved11[4];
+ u8 ip; /* PSC + 0x44 */
+ u8 reserved12[3];
+ u8 op1; /* PSC + 0x48 */
+ u8 reserved13[3];
+ u8 op0; /* PSC + 0x4c */
+ u8 reserved14[3];
+ u32 sicr; /* PSC + 0x50 */
+ u8 reserved15[4]; /* make eq. sizeof(mpc52xx_psc) */
+};
+
#endif /* __ASM_MPC52xx_PSC_H__ */
diff --git a/drivers/tty/serial/mpc52xx_uart.c
b/drivers/tty/serial/mpc52xx_uart.c
index a0bcd8a..b53c03a 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -121,6 +121,15 @@ struct psc_ops {
void (*fifoc_uninit)(void);
void (*get_irq)(struct uart_port *, struct device_node *);
irqreturn_t (*handle_irq)(struct uart_port *port);
+ u16 (*get_status)(struct uart_port *port);
+ u8 (*get_ipcr)(struct uart_port *port);
+ void (*command)(struct uart_port *port, u8 cmd);
+ void (*set_mode)(struct uart_port *port, u8 mr1, u8 mr2);
+ void (*set_rts)(struct uart_port *port, int state);
+ void (*enable_ms)(struct uart_port *port);
+ void (*set_sicr)(struct uart_port *port, u32 val);
+ void (*set_imr)(struct uart_port *port, u16 val);
+ u8 (*get_mr1)(struct uart_port *port);
};
/* setting the prescaler and divisor reg is common for all chips */
@@ -133,6 +142,74 @@ static inline void mpc52xx_set_divisor(struct
mpc52xx_psc __iomem *psc,
out_8(&psc->ctlr, divisor & 0xff);
}
+static inline void mpc5125_set_divisor(struct mpc5125_psc __iomem *psc,
+ u8 prescaler, unsigned int divisor)
+{
+ /* select prescaler */
+ out_8(&psc->mpc52xx_psc_clock_select, prescaler);
+ out_8(&psc->ctur, divisor >> 8);
+ out_8(&psc->ctlr, divisor & 0xff);
+}
+
+static u16 mpc52xx_psc_get_status(struct uart_port *port)
+{
+ return in_be16(&PSC(port)->mpc52xx_psc_status);
+}
+
+static u8 mpc52xx_psc_get_ipcr(struct uart_port *port)
+{
+ return in_8(&PSC(port)->mpc52xx_psc_ipcr);
+}
+
+static void mpc52xx_psc_command(struct uart_port *port, u8 cmd)
+{
+ out_8(&PSC(port)->command, cmd);
+}
+
+static void mpc52xx_psc_set_mode(struct uart_port *port, u8 mr1, u8 mr2)
+{
+ out_8(&PSC(port)->command, MPC52xx_PSC_SEL_MODE_REG_1);
+ out_8(&PSC(port)->mode, mr1);
+ out_8(&PSC(port)->mode, mr2);
+}
+
+static void mpc52xx_psc_set_rts(struct uart_port *port, int state)
+{
+ if (state)
+ out_8(&PSC(port)->op1, MPC52xx_PSC_OP_RTS);
+ else
+ out_8(&PSC(port)->op0, MPC52xx_PSC_OP_RTS);
+}
+
+static void mpc52xx_psc_enable_ms(struct uart_port *port)
+{
+ struct mpc52xx_psc __iomem *psc = PSC(port);
+
+ /* clear D_*-bits by reading them */
+ in_8(&psc->mpc52xx_psc_ipcr);
+ /* enable CTS and DCD as IPC interrupts */
+ out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
+
+ port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
+ out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+}
+
+static void mpc52xx_psc_set_sicr(struct uart_port *port, u32 val)
+{
+ out_be32(&PSC(port)->sicr, val);
+}
+
+static void mpc52xx_psc_set_imr(struct uart_port *port, u16 val)
+{
+ out_be16(&PSC(port)->mpc52xx_psc_imr, val);
+}
+
+static u8 mpc52xx_psc_get_mr1(struct uart_port *port)
+{
+ out_8(&PSC(port)->command, MPC52xx_PSC_SEL_MODE_REG_1);
+ return in_8(&PSC(port)->mode);
+}
+
#ifdef CONFIG_PPC_MPC52xx
#define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
static void mpc52xx_psc_fifo_init(struct uart_port *port)
@@ -302,6 +379,15 @@ static struct psc_ops mpc52xx_psc_ops = {
.set_baudrate = mpc5200_psc_set_baudrate,
.get_irq = mpc52xx_psc_get_irq,
.handle_irq = mpc52xx_psc_handle_irq,
+ .get_status = mpc52xx_psc_get_status,
+ .get_ipcr = mpc52xx_psc_get_ipcr,
+ .command = mpc52xx_psc_command,
+ .set_mode = mpc52xx_psc_set_mode,
+ .set_rts = mpc52xx_psc_set_rts,
+ .enable_ms = mpc52xx_psc_enable_ms,
+ .set_sicr = mpc52xx_psc_set_sicr,
+ .set_imr = mpc52xx_psc_set_imr,
+ .get_mr1 = mpc52xx_psc_get_mr1,
};
static struct psc_ops mpc5200b_psc_ops = {
@@ -323,6 +409,15 @@ static struct psc_ops mpc5200b_psc_ops = {
.set_baudrate = mpc5200b_psc_set_baudrate,
.get_irq = mpc52xx_psc_get_irq,
.handle_irq = mpc52xx_psc_handle_irq,
+ .get_status = mpc52xx_psc_get_status,
+ .get_ipcr = mpc52xx_psc_get_ipcr,
+ .command = mpc52xx_psc_command,
+ .set_mode = mpc52xx_psc_set_mode,
+ .set_rts = mpc52xx_psc_set_rts,
+ .enable_ms = mpc52xx_psc_enable_ms,
+ .set_sicr = mpc52xx_psc_set_sicr,
+ .set_imr = mpc52xx_psc_set_imr,
+ .get_mr1 = mpc52xx_psc_get_mr1,
};
#endif /* CONFIG_MPC52xx */
@@ -593,9 +688,253 @@ static struct psc_ops mpc512x_psc_ops = {
.fifoc_uninit = mpc512x_psc_fifoc_uninit,
.get_irq = mpc512x_psc_get_irq,
.handle_irq = mpc512x_psc_handle_irq,
+ .get_status = mpc52xx_psc_get_status,
+ .get_ipcr = mpc52xx_psc_get_ipcr,
+ .command = mpc52xx_psc_command,
+ .set_mode = mpc52xx_psc_set_mode,
+ .set_rts = mpc52xx_psc_set_rts,
+ .enable_ms = mpc52xx_psc_enable_ms,
+ .set_sicr = mpc52xx_psc_set_sicr,
+ .set_imr = mpc52xx_psc_set_imr,
+ .get_mr1 = mpc52xx_psc_get_mr1,
};
#endif
+#if defined(CONFIG_PPC_MPC5125) && defined(CONFIG_PPC_MPC512x)
+#define PSC_5125(port) ((struct mpc5125_psc __iomem *)((port)->membase))
+#define FIFO_5125(port) ((struct mpc512x_psc_fifo __iomem *)(PSC_5125(port)+1))
+
+static void mpc5125_psc_fifo_init(struct uart_port *port)
+{
+ /* /32 prescaler */
+ out_8(&PSC_5125(port)->mpc52xx_psc_clock_select, 0xdd);
+
+ out_be32(&FIFO_5125(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE);
+ out_be32(&FIFO_5125(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
+ out_be32(&FIFO_5125(port)->txalarm, 1);
+ out_be32(&FIFO_5125(port)->tximr, 0);
+
+ out_be32(&FIFO_5125(port)->rxcmd, MPC512x_PSC_FIFO_RESET_SLICE);
+ out_be32(&FIFO_5125(port)->rxcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
+ out_be32(&FIFO_5125(port)->rxalarm, 1);
+ out_be32(&FIFO_5125(port)->rximr, 0);
+
+ out_be32(&FIFO_5125(port)->tximr, MPC512x_PSC_FIFO_ALARM);
+ out_be32(&FIFO_5125(port)->rximr, MPC512x_PSC_FIFO_ALARM);
+}
+
+static int mpc5125_psc_raw_rx_rdy(struct uart_port *port)
+{
+ return !(in_be32(&FIFO_5125(port)->rxsr) & MPC512x_PSC_FIFO_EMPTY);
+}
+
+static int mpc5125_psc_raw_tx_rdy(struct uart_port *port)
+{
+ return !(in_be32(&FIFO_5125(port)->txsr) & MPC512x_PSC_FIFO_FULL);
+}
+
+static int mpc5125_psc_rx_rdy(struct uart_port *port)
+{
+ return in_be32(&FIFO_5125(port)->rxsr)
+ & in_be32(&FIFO_5125(port)->rximr)
+ & MPC512x_PSC_FIFO_ALARM;
+}
+
+static int mpc5125_psc_tx_rdy(struct uart_port *port)
+{
+ return in_be32(&FIFO_5125(port)->txsr)
+ & in_be32(&FIFO_5125(port)->tximr)
+ & MPC512x_PSC_FIFO_ALARM;
+}
+
+static int mpc5125_psc_tx_empty(struct uart_port *port)
+{
+ return in_be32(&FIFO_5125(port)->txsr)
+ & MPC512x_PSC_FIFO_EMPTY;
+}
+
+static void mpc5125_psc_stop_rx(struct uart_port *port)
+{
+ unsigned long rx_fifo_imr;
+
+ rx_fifo_imr = in_be32(&FIFO_5125(port)->rximr);
+ rx_fifo_imr &= ~MPC512x_PSC_FIFO_ALARM;
+ out_be32(&FIFO_5125(port)->rximr, rx_fifo_imr);
+}
+
+static void mpc5125_psc_start_tx(struct uart_port *port)
+{
+ unsigned long tx_fifo_imr;
+
+ tx_fifo_imr = in_be32(&FIFO_5125(port)->tximr);
+ tx_fifo_imr |= MPC512x_PSC_FIFO_ALARM;
+ out_be32(&FIFO_5125(port)->tximr, tx_fifo_imr);
+}
+
+static void mpc5125_psc_stop_tx(struct uart_port *port)
+{
+ unsigned long tx_fifo_imr;
+
+ tx_fifo_imr = in_be32(&FIFO_5125(port)->tximr);
+ tx_fifo_imr &= ~MPC512x_PSC_FIFO_ALARM;
+ out_be32(&FIFO_5125(port)->tximr, tx_fifo_imr);
+}
+
+static void mpc5125_psc_rx_clr_irq(struct uart_port *port)
+{
+ out_be32(&FIFO_5125(port)->rxisr, in_be32(&FIFO_5125(port)->rxisr));
+}
+
+static void mpc5125_psc_tx_clr_irq(struct uart_port *port)
+{
+ out_be32(&FIFO_5125(port)->txisr, in_be32(&FIFO_5125(port)->txisr));
+}
+
+static void mpc5125_psc_write_char(struct uart_port *port, unsigned char c)
+{
+ out_8(&FIFO_5125(port)->txdata_8, c);
+}
+
+static unsigned char mpc5125_psc_read_char(struct uart_port *port)
+{
+ return in_8(&FIFO_5125(port)->rxdata_8);
+}
+
+static void mpc5125_psc_cw_disable_ints(struct uart_port *port)
+{
+ port->read_status_mask =
+ in_be32(&FIFO_5125(port)->tximr) << 16 |
+ in_be32(&FIFO_5125(port)->rximr);
+ out_be32(&FIFO_5125(port)->tximr, 0);
+ out_be32(&FIFO_5125(port)->rximr, 0);
+}
+
+static void mpc5125_psc_cw_restore_ints(struct uart_port *port)
+{
+ out_be32(&FIFO_5125(port)->tximr,
+ (port->read_status_mask >> 16) & 0x7f);
+ out_be32(&FIFO_5125(port)->rximr, port->read_status_mask & 0x7f);
+}
+
+static unsigned int mpc5125_psc_set_baudrate(struct uart_port *port,
+ struct ktermios *new,
+ struct ktermios *old)
+{
+ unsigned int baud;
+ unsigned int divisor;
+
+ /*
+ * Calculate with a /16 prescaler here.
+ */
+
+ /* uartclk contains the ips freq */
+ baud = uart_get_baud_rate(port, new, old,
+ port->uartclk / (16 * 0xffff) + 1,
+ port->uartclk / 16);
+ divisor = (port->uartclk + 8 * baud) / (16 * baud);
+
+ /* enable the /16 prescaler and set the divisor */
+ mpc5125_set_divisor(PSC_5125(port), 0xdd, divisor);
+ return baud;
+}
+
+/* MPC5125 have compatible PSC FIFO Controller.
+ * Special init not needed.
+ */
+
+static u16 mpc5125_psc_get_status(struct uart_port *port)
+{
+ return in_be16(&PSC_5125(port)->mpc52xx_psc_status);
+}
+
+static u8 mpc5125_psc_get_ipcr(struct uart_port *port)
+{
+ return in_8(&PSC_5125(port)->mpc52xx_psc_ipcr);
+}
+
+static void mpc5125_psc_command(struct uart_port *port, u8 cmd)
+{
+ out_8(&PSC_5125(port)->command, cmd);
+}
+
+static void mpc5125_psc_set_mode(struct uart_port *port, u8 mr1, u8 mr2)
+{
+ out_8(&PSC_5125(port)->mr1, mr1);
+ out_8(&PSC_5125(port)->mr2, mr2);
+}
+
+static void mpc5125_psc_set_rts(struct uart_port *port, int state)
+{
+ if (state & TIOCM_RTS)
+ out_8(&PSC_5125(port)->op1, MPC52xx_PSC_OP_RTS);
+ else
+ out_8(&PSC_5125(port)->op0, MPC52xx_PSC_OP_RTS);
+}
+
+static void
+mpc5125_psc_enable_ms(struct uart_port *port)
+{
+ struct mpc5125_psc __iomem *psc = PSC_5125(port);
+
+ /* clear D_*-bits by reading them */
+ in_8(&psc->mpc52xx_psc_ipcr);
+ /* enable CTS and DCD as IPC interrupts */
+ out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
+
+ port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
+ out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+}
+
+static void mpc5125_psc_set_sicr(struct uart_port *port, u32 val)
+{
+ out_be32(&PSC_5125(port)->sicr, val);
+}
+
+static void mpc5125_psc_set_imr(struct uart_port *port, u16 val)
+{
+ out_be16(&PSC_5125(port)->mpc52xx_psc_imr, val);
+}
+
+static u8 mpc5125_psc_get_mr1(struct uart_port *port)
+{
+ return in_8(&PSC_5125(port)->mr1);
+}
+
+static struct psc_ops mpc5125_psc_ops = {
+ .fifo_init = mpc5125_psc_fifo_init,
+ .raw_rx_rdy = mpc5125_psc_raw_rx_rdy,
+ .raw_tx_rdy = mpc5125_psc_raw_tx_rdy,
+ .rx_rdy = mpc5125_psc_rx_rdy,
+ .tx_rdy = mpc5125_psc_tx_rdy,
+ .tx_empty = mpc5125_psc_tx_empty,
+ .stop_rx = mpc5125_psc_stop_rx,
+ .start_tx = mpc5125_psc_start_tx,
+ .stop_tx = mpc5125_psc_stop_tx,
+ .rx_clr_irq = mpc5125_psc_rx_clr_irq,
+ .tx_clr_irq = mpc5125_psc_tx_clr_irq,
+ .write_char = mpc5125_psc_write_char,
+ .read_char = mpc5125_psc_read_char,
+ .cw_disable_ints = mpc5125_psc_cw_disable_ints,
+ .cw_restore_ints = mpc5125_psc_cw_restore_ints,
+ .set_baudrate = mpc5125_psc_set_baudrate,
+ .clock = mpc512x_psc_clock,
+ .fifoc_init = mpc512x_psc_fifoc_init,
+ .fifoc_uninit = mpc512x_psc_fifoc_uninit,
+ .get_irq = mpc512x_psc_get_irq,
+ .handle_irq = mpc512x_psc_handle_irq,
+ .get_status = mpc5125_psc_get_status,
+ .get_ipcr = mpc5125_psc_get_ipcr,
+ .command = mpc5125_psc_command,
+ .set_mode = mpc5125_psc_set_mode,
+ .set_rts = mpc5125_psc_set_rts,
+ .enable_ms = mpc5125_psc_enable_ms,
+ .set_sicr = mpc5125_psc_set_sicr,
+ .set_imr = mpc5125_psc_set_imr,
+ .get_mr1 = mpc5125_psc_get_mr1,
+};
+#endif /* CONFIG_PPC_MPC5125 */
+
+
static struct psc_ops *psc_ops;
/* ======================================================================== */
@@ -611,17 +950,14 @@ mpc52xx_uart_tx_empty(struct uart_port *port)
static void
mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- if (mctrl & TIOCM_RTS)
- out_8(&PSC(port)->op1, MPC52xx_PSC_OP_RTS);
- else
- out_8(&PSC(port)->op0, MPC52xx_PSC_OP_RTS);
+ psc_ops->set_rts(port, mctrl & TIOCM_RTS);
}
static unsigned int
mpc52xx_uart_get_mctrl(struct uart_port *port)
{
unsigned int ret = TIOCM_DSR;
- u8 status = in_8(&PSC(port)->mpc52xx_psc_ipcr);
+ u8 status = psc_ops->get_ipcr(port);
if (!(status & MPC52xx_PSC_CTS))
ret |= TIOCM_CTS;
@@ -671,15 +1007,7 @@ mpc52xx_uart_stop_rx(struct uart_port *port)
static void
mpc52xx_uart_enable_ms(struct uart_port *port)
{
- struct mpc52xx_psc __iomem *psc = PSC(port);
-
- /* clear D_*-bits by reading them */
- in_8(&psc->mpc52xx_psc_ipcr);
- /* enable CTS and DCD as IPC interrupts */
- out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
-
- port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
- out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+ psc_ops->enable_ms(port);
}
static void
@@ -689,9 +1017,9 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl)
spin_lock_irqsave(&port->lock, flags);
if (ctl == -1)
- out_8(&PSC(port)->command, MPC52xx_PSC_START_BRK);
+ psc_ops->command(port, MPC52xx_PSC_START_BRK);
else
- out_8(&PSC(port)->command, MPC52xx_PSC_STOP_BRK);
+ psc_ops->command(port, MPC52xx_PSC_STOP_BRK);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -699,7 +1027,6 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl)
static int
mpc52xx_uart_startup(struct uart_port *port)
{
- struct mpc52xx_psc __iomem *psc = PSC(port);
int ret;
if (psc_ops->clock) {
@@ -715,15 +1042,15 @@ mpc52xx_uart_startup(struct uart_port *port)
return ret;
/* Reset/activate the port, clear and enable interrupts */
- out_8(&psc->command, MPC52xx_PSC_RST_RX);
- out_8(&psc->command, MPC52xx_PSC_RST_TX);
+ psc_ops->command(port, MPC52xx_PSC_RST_RX);
+ psc_ops->command(port, MPC52xx_PSC_RST_TX);
- out_be32(&psc->sicr, 0); /* UART mode DCD ignored */
+ psc_ops->set_sicr(port, 0); /* UART mode DCD ignored */
psc_ops->fifo_init(port);
- out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
- out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
+ psc_ops->command(port, MPC52xx_PSC_TX_ENABLE);
+ psc_ops->command(port, MPC52xx_PSC_RX_ENABLE);
return 0;
}
@@ -731,15 +1058,13 @@ mpc52xx_uart_startup(struct uart_port *port)
static void
mpc52xx_uart_shutdown(struct uart_port *port)
{
- struct mpc52xx_psc __iomem *psc = PSC(port);
-
/* Shut down the port. Leave TX active if on a console port */
- out_8(&psc->command, MPC52xx_PSC_RST_RX);
+ psc_ops->command(port, MPC52xx_PSC_RST_RX);
if (!uart_console(port))
- out_8(&psc->command, MPC52xx_PSC_RST_TX);
+ psc_ops->command(port, MPC52xx_PSC_RST_TX);
port->read_status_mask = 0;
- out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
+ psc_ops->set_imr(port, port->read_status_mask);
if (psc_ops->clock)
psc_ops->clock(port, 0);
@@ -752,7 +1077,6 @@ static void
mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
struct ktermios *old)
{
- struct mpc52xx_psc __iomem *psc = PSC(port);
unsigned long flags;
unsigned char mr1, mr2;
unsigned int j;
@@ -812,13 +1136,11 @@ mpc52xx_uart_set_termios(struct uart_port
*port, struct ktermios *new,
"Some chars may have been lost.\n");
/* Reset the TX & RX */
- out_8(&psc->command, MPC52xx_PSC_RST_RX);
- out_8(&psc->command, MPC52xx_PSC_RST_TX);
+ psc_ops->command(port, MPC52xx_PSC_RST_RX);
+ psc_ops->command(port, MPC52xx_PSC_RST_TX);
/* Send new mode settings */
- out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
- out_8(&psc->mode, mr1);
- out_8(&psc->mode, mr2);
+ psc_ops->set_mode(port, mr1, mr2);
baud = psc_ops->set_baudrate(port, new, old);
/* Update the per-port timeout */
@@ -828,8 +1150,8 @@ mpc52xx_uart_set_termios(struct uart_port *port,
struct ktermios *new,
mpc52xx_uart_enable_ms(port);
/* Reenable TX & RX */
- out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
- out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
+ psc_ops->command(port, MPC52xx_PSC_TX_ENABLE);
+ psc_ops->command(port, MPC52xx_PSC_RX_ENABLE);
/* We're all set, release the lock */
spin_unlock_irqrestore(&port->lock, flags);
@@ -957,7 +1279,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
flag = TTY_NORMAL;
port->icount.rx++;
- status = in_be16(&PSC(port)->mpc52xx_psc_status);
+ status = psc_ops->get_status(port);
if (status & (MPC52xx_PSC_SR_PE |
MPC52xx_PSC_SR_FE |
@@ -977,7 +1299,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
}
/* Clear error condition */
- out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT);
+ psc_ops->command(port, MPC52xx_PSC_RST_ERR_STAT);
}
tty_insert_flip_char(tty, ch, flag);
@@ -1060,7 +1382,7 @@ mpc5xxx_uart_process_int(struct uart_port *port)
if (psc_ops->tx_rdy(port))
keepgoing |= mpc52xx_uart_int_tx_chars(port);
- status = in_8(&PSC(port)->mpc52xx_psc_ipcr);
+ status = psc_ops->get_ipcr(port);
if (status & MPC52xx_PSC_D_DCD)
uart_handle_dcd_change(port, !(status & MPC52xx_PSC_DCD));
@@ -1101,14 +1423,12 @@ static void __init
mpc52xx_console_get_options(struct uart_port *port,
int *baud, int *parity, int *bits, int *flow)
{
- struct mpc52xx_psc __iomem *psc = PSC(port);
unsigned char mr1;
pr_debug("mpc52xx_console_get_options(port=%p)\n", port);
/* Read the mode registers */
- out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
- mr1 = in_8(&psc->mode);
+ mr1 = psc_ops->get_mr1(port);
/* CT{U,L}R are write-only ! */
*baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
@@ -1299,6 +1619,10 @@ static struct of_device_id mpc52xx_uart_of_match[] = {
#ifdef CONFIG_PPC_MPC512x
{ .compatible = "fsl,mpc5121-psc-uart", .data = &mpc512x_psc_ops, },
#endif
+#ifdef CONFIG_PPC_MPC5125
+ { .compatible = "fsl,mpc5125-psc-uart", .data = &mpc5125_psc_ops, },
+#endif
+
{},
};
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 1/3, v4] powerpc/mpc512x: Add initial support for TWR-MPC5125
From: vooon341 @ 2011-03-22 14:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras, linux-kernel
In-Reply-To: <AANLkTimDDpCHf7Cpjt5mi=d18OpX2Q4yiwNDK_26j0kD@mail.gmail.com>
Adds Freescale TWR-MPC5125 device tree and platform code.
Currently following is supported:
- NAND
- FEC1 and FEC2
- RTC
- PSC UART
NAND flash controller require more tests, so it will be later.
Signed-off-by: Vladimir Ermakov <vooon341@gmail.com>
---
v2:
- add PSC compat string selection
- add ioctl defines
v3:
- less verbose interrupt-parent
- move mpc512x_select_psc_compat() to mpc512x_shared.c
- remove unneded mpc5125_psc_iopad_init()
- fix board prefixes
v4:
- remove device_type from ethernet nodes
- add aliases for ethernet nodes
- add phy-connection-type
- extend size of rootfs partition
---
arch/powerpc/boot/dts/mpc5125twr.dts | 376 ++++++++++++++++++++++++++
arch/powerpc/platforms/512x/Kconfig | 14 +
arch/powerpc/platforms/512x/Makefile | 1 +
arch/powerpc/platforms/512x/clock.c | 9 +-
arch/powerpc/platforms/512x/mpc5125_twr.c | 142 ++++++++++
arch/powerpc/platforms/512x/mpc512x.h | 5 +-
arch/powerpc/platforms/512x/mpc512x_shared.c | 26 ++-
7 files changed, 569 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc5125twr.dts
b/arch/powerpc/boot/dts/mpc5125twr.dts
new file mode 100644
index 0000000..ca3851d
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc5125twr.dts
@@ -0,0 +1,376 @@
+/*
+ * STx/Freescale ADS5125 MPC5125 silicon
+ *
+ * Copyright (C) 2009 Freescale Semiconductor Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "mpc5125twr"; // In BSP "mpc5125ads"
+ compatible = "fsl,mpc5125ads";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&ipic>;
+
+ aliases {
+ ethernet0 = ð0;
+ ethernet1 = ð1;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,5125@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <0x20>; // 32 bytes
+ i-cache-line-size = <0x20>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <49500000>;// 49.5 MHz (csb/4)
+ bus-frequency = <198000000>; // 198 MHz csb bus
+ clock-frequency = <396000000>; // 396 MHz ppc core
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x10000000>; // 256MB at 0
+ };
+
+ sram@30000000 {
+ compatible = "fsl,mpc5121-sram";
+ reg = <0x30000000 0x08000>; // 32K at 0x30000000
+ };
+
+ nfc@40000000 {
+ compatible = "fsl,mpc5125-nfc";
+ reg = <0x40000000 0x100000>; // 1M at 0x40000000
+ interrupts = <6 0x8>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ bank-width = <1>;
+ write-size = <4096>;
+ spare-size = <128>;
+ chips = <1>;
+ // NOTE: partition map different than in BSP
+ // First three is the same as in BSP, other differ.
+ nand-spl@0 {
+ label = "loader";
+ reg = <0x00000000 0x00100000>;
+ read-only;
+ };
+ uboot@100000 {
+ label = "uboot";
+ reg = <0x00100000 0x00100000>;
+ read-only;
+ };
+ uboot-env@200000 {
+ label = "uboot-env";
+ reg = <0x00200000 0x00100000>;
+ read-only;
+ };
+ kernel@300000 {
+ label = "kernel";
+ reg = <0x00300000 0x00800000>;
+ };
+ device-tree@b00000 {
+ label = "device-tree";
+ reg = <0x00b00000 0x00100000>;
+ };
+ ramboot-rootfs@c00000 {
+ label = "ramboot-rootfs";
+ reg = <0x00c00000 0x00800000>;
+ };
+ rootfs@1400000 {
+ label = "rootfs";
+ reg = <0x01400000 0x02800000>;
+ };
+ user@2800000 {
+ label = "user";
+ reg = <0x03C00000 0x01400000>;
+ };
+ SRAM@4200000 {
+ label = "SRAM"; // NVRAM emul
+ reg = <0x05000000 0x01400000>;
+ };
+ prom@5600000 {
+ label = "prom";
+ reg = <0x06400000 0x01400000>;
+ };
+ //data@2800000 {
+ // label = "data";
+ // reg = <0x28000000 0xeac00000>;
+ //};
+ };
+
+ soc@80000000 {
+ compatible = "fsl,mpc5121-immr";
+ device_type = "soc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ ranges = <0x0 0x80000000 0x400000>;
+ reg = <0x80000000 0x400000>;
+ bus-frequency = <66000000>; // 66 MHz ips bus
+
+ // IPIC
+ // interrupts cell = <intr #, sense>
+ // sense values match linux IORESOURCE_IRQ_* defines:
+ // sense == 8: Level, low assertion
+ // sense == 2: Edge, high-to-low change
+ //
+ ipic: interrupt-controller@c00 {
+ compatible = "fsl,mpc5121-ipic", "fsl,ipic";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0xc00 0x100>;
+ };
+
+ rtc@a00 { // Real time clock
+ compatible = "fsl,mpc5121-rtc";
+ reg = <0xa00 0x100>;
+ interrupts = <79 0x8 80 0x8>;
+ };
+
+ reset@e00 { // Reset module
+ compatible = "fsl,mpc5121-reset";
+ reg = <0xe00 0x100>;
+ };
+
+ clock@f00 { // Clock control
+ compatible = "fsl,mpc5121rev2-clock", "fsl,mpc5121-clock";
+ reg = <0xf00 0x100>;
+ };
+
+ pmc@1000{ // Power Management Controller
+ compatible = "fsl,mpc5121-pmc";
+ reg = <0x1000 0x100>;
+ interrupts = <83 0x2>;
+ };
+
+ gpio@1100 {
+ compatible = "fsl,mpc5125-gpio";
+ cell-index = <0>;
+ reg = <0x1100 0x080>;
+ interrupts = <78 0x8>;
+ };
+
+ gpio@1180 {
+ compatible = "fsl,mpc5125-gpio1";
+ cell-index = <1>;
+ reg = <0x1180 0x080>;
+ interrupts = <78 0x8>;
+ };
+
+ can@1300 { // CAN rev.2
+ compatible = "fsl,mpc5121-mscan";
+ cell-index = <0>;
+ interrupts = <12 0x8>;
+ reg = <0x1300 0x80>;
+ };
+
+ can@1380 {
+ compatible = "fsl,mpc5121-mscan";
+ cell-index = <1>;
+ interrupts = <13 0x8>;
+ reg = <0x1380 0x80>;
+ };
+
+ sdhc@1500 {
+ compatible = "fsl,mpc5125-sdhc";
+ interrupts = <8 0x8>;
+ reg = <0x1500 0x100>;
+ };
+
+ i2c@1700 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-i2c";
+ cell-index = <0>;
+ reg = <0x1700 0x20>;
+ interrupts = <0x9 0x8>;
+ fsl5200-clocking;
+ };
+
+ i2c@1720 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-i2c";
+ cell-index = <1>;
+ reg = <0x1720 0x20>;
+ interrupts = <0xa 0x8>;
+ fsl5200-clocking;
+ };
+
+ i2c@1740 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-i2c";
+ cell-index = <2>;
+ reg = <0x1740 0x20>;
+ interrupts = <0xb 0x8>;
+ fsl5200-clocking;
+ };
+
+ i2ccontrol@1760 {
+ compatible = "fsl,mpc5121-i2c-ctrl";
+ reg = <0x1760 0x8>;
+ };
+
+ //diu@2100 {
+ // device_type = "display";
+ // compatible = "fsl-diu";
+ // reg = <0x2100 0x100>;
+ // interrupts = <64 0x8>;
+ //};
+
+ // MPC5125e has two more CAN ports
+ // but they are not used on ADS5125
+ //can@2300 {
+ // compatible = "fsl,mpc5121-mscan";
+ // cell-index = <2>;
+ // interrupts = <90 0x8>;
+ // reg = <0x2300 0x80>;
+ //};
+
+ //can@2380 {
+ // compatible = "fsl,mpc5121-mscan";
+ // cell-index = <3>;
+ // interrupts = <91 0x8>;
+ // reg = <0x2380 0x80>;
+ //};
+
+ mdio@2800 {
+ compatible = "fsl,mpc5121-fec-mdio";
+ reg = <0x2800 0x800>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy0: ethernet-phy@0 {
+ compatible = "smsc,lan8710";
+ reg = <1>;
+ };
+ };
+
+ eth0: ethernet@2800 {
+ compatible = "fsl,mpc5121-fec";
+ reg = <0x2800 0x800>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <4 0x8>;
+ phy-handle = < &phy0 >;
+ phy-connection-type = "rmii";
+ };
+
+ // USB ULPI1
+ //usb@3000 {
+ // device_type = "usb";
+ // compatible = "fsl-usb2-dr";
+ // reg = <0x3000 0x400>;
+ // #address-cells = <1>;
+ // #size-cells = <0>;
+ // interrupts = <43 0x8>;
+ // dr_mode = "host";
+ // phy_type = "ulpi";
+ // big-endian-regs;
+ //};
+
+ // USB ULPI2
+ //usb@4000 {
+ // device_type = "usb";
+ // compatible = "fsl-usb2-dr";
+ // reg = <0x4000 0x400>;
+ // #address-cells = <1>;
+ // #size-cells = <0>;
+ // interrupts = <44 0x8>;
+ // dr_mode = "otg";
+ // phy_type = "ulpi";
+ // big-endian-regs;
+ //};
+
+ mdio@4800 {
+ compatible = "fsl,mpc5121-fec-mdio";
+ reg = <0x4800 0x800>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy1: ethernet-phy@0 {
+ compatible = "micrel,ksz8041";
+ reg = <1>;
+ };
+ };
+
+ eth1: ethernet@4800 {
+ device_type = "network";
+ compatible = "fsl,mpc5121-fec";
+ reg = <0x4800 0x800>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <5 0x8>;
+ phy-handle = < &phy1 >;
+ phy-connection-type = "rmii";
+ };
+
+ // IO control
+ ioctl@a000 {
+ compatible = "fsl,mpc5125-ioctl";
+ reg = <0xA000 0x1000>;
+ };
+
+ // PSC0 in ac97 mode
+ //ac97@11000 {
+ // device_type = "sound";
+ // compatible = "fsl,mpc5125-psc-ac97", "fsl,mpc5125-psc";
+ // cell-index = <0>;
+ // reg = <0x11000 0x100>;
+ // interrupts = <40 0x8>;
+ // fsl,mode = "ac97-slave";
+ // rx-fifo-size = <384>;
+ // tx-fifo-size = <384>;
+ //};
+
+ // 5125 PSCs are not 52xx or 5121 PSC compatible
+ // PSC1 uart0 aka ttyPSC0
+ serial@11100 {
+ device_type = "serial";
+ compatible = "fsl,mpc5125-psc-uart", "fsl,mpc5125-psc";
+ port-number = <0>;
+ cell-index = <1>;
+ reg = <0x11100 0x100>;
+ interrupts = <40 0x8 71 0x8>;
+ fsl,rx-fifo-size = <16>;
+ fsl,tx-fifo-size = <16>;
+ nodcd;
+ };
+
+ // PSC9 uart1 aka ttyPSC1
+ serial@11900 {
+ device_type = "serial";
+ compatible = "fsl,mpc5125-psc-uart", "fsl,mpc5125-psc";
+ port-number = <1>;
+ cell-index = <9>;
+ reg = <0x11900 0x100>;
+ interrupts = <40 0x8 32 0x8>;
+ fsl,rx-fifo-size = <16>;
+ fsl,tx-fifo-size = <16>;
+ nodcd;
+ };
+
+ pscfifo@11f00 {
+ compatible = "fsl,mpc5121-psc-fifo";
+ reg = <0x11f00 0x100>;
+ interrupts = <40 0x8>;
+ };
+
+ dma@14000 {
+ compatible = "fsl,mpc5121-dma"; // BSP name: "mpc512x-dma2"
+ reg = <0x14000 0x1800>;
+ interrupts = <65 0x8>;
+ };
+ };
+};
diff --git a/arch/powerpc/platforms/512x/Kconfig
b/arch/powerpc/platforms/512x/Kconfig
index 27b0651..0dde4b0 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -26,6 +26,20 @@ config MPC5121_GENERIC
Compatible boards include: Protonic LVT base boards (ZANMCU
and VICVT2).
+config PPC_MPC5125
+ bool "Generic support for MPC5125 based boards"
+ depends on PPC_MPC512x
+ select DEFAULT_UIMAGE
+ select PPC_INDIRECT_PCI
+ default n
+
+config MPC5125_TWR
+ bool "Freescale MPC5125 Tower system"
+ depends on PPC_MPC512x
+ select PPC_MPC5125
+ help
+ This option enables support for the MPC5125 TWR board.
+
config PDM360NG
bool "ifm PDM360NG board"
depends on PPC_MPC512x
diff --git a/arch/powerpc/platforms/512x/Makefile
b/arch/powerpc/platforms/512x/Makefile
index 4efc1c4..5c17561 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -5,3 +5,4 @@ obj-y += clock.o mpc512x_shared.o
obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o
obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o
obj-$(CONFIG_PDM360NG) += pdm360ng.o
+obj-$(CONFIG_MPC5125_TWR) += mpc5125_twr.o
diff --git a/arch/powerpc/platforms/512x/clock.c
b/arch/powerpc/platforms/512x/clock.c
index 3dc2a8d..07e0bc0 100644
--- a/arch/powerpc/platforms/512x/clock.c
+++ b/arch/powerpc/platforms/512x/clock.c
@@ -27,6 +27,8 @@
#include <asm/mpc5xxx.h>
#include <asm/clk_interface.h>
+#include "mpc512x.h"
+
#undef CLK_DEBUG
static int clocks_initialized;
@@ -679,8 +681,13 @@ static void psc_clks_init(void)
struct device_node *np;
const u32 *cell_index;
struct platform_device *ofdev;
+ char *psc_compat;
+
+ psc_compat = mpc512x_select_psc_compat();
+ if (!psc_compat)
+ return;
- for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") {
+ for_each_compatible_node(np, NULL, psc_compat) {
cell_index = of_get_property(np, "cell-index", NULL);
if (cell_index) {
int pscnum = *cell_index;
diff --git a/arch/powerpc/platforms/512x/mpc5125_twr.c
b/arch/powerpc/platforms/512x/mpc5125_twr.c
new file mode 100644
index 0000000..7c7facf
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc5125_twr.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2010 LimePC Multimedia Technologies Co., Limited
+ * Copyright (C) 2011 Vladimir Ermakov <vooon341@gmail.com>
+ *
+ * Based on original Freescale Semiconductor BSP
+ * written by Cloudy Chen <chen_yunsong@mtcera.com>
+ *
+ * MPC5125 Tower board setup
+ *
+ * This 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 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/machdep.h>
+#include <asm/ipic.h>
+#include <asm/prom.h>
+#include <asm/time.h>
+
+#include <sysdev/fsl_soc.h>
+
+#include <linux/bootmem.h>
+#include <asm/rheap.h>
+
+#include "mpc512x.h"
+
+/* IOCTL registers for USB1/FEC2 */
+#define IOCTL_USB1_DATA0 0x63
+#define IOCTL_USB1_DATA1 0x64
+#define IOCTL_USB1_DATA2 0x65
+#define IOCTL_USB1_DATA3 0x66
+#define IOCTL_USB1_DATA4 0x67
+#define IOCTL_USB1_DATA5 0x68
+#define IOCTL_USB1_DATA6 0x69
+#define IOCTL_USB1_DATA7 0x6A
+#define IOCTL_USB1_STOP 0x6B
+#define IOCTL_USB1_CLK 0x6C
+#define IOCTL_USB1_NEXT 0x6D
+#define IOCTL_USB1_DIR 0x6E
+
+/* Pin modes */
+#define IOCTL_DEFAULT_MODE 0x03 /* FUNCMUX=0, PUD=0, PUE=0, DS=3 */
+#define IOCTL_FEC2_MODE 0x43 /* FUNCMUX=2, PUD=0, PUE=0, DS=3 */
+
+/* Select mode of USB1 pads.
+ * They could be configured as USB (default), FEC2
+ * and several PSC's and/or GPIO's.
+ * Board specific. It can be platform specific in the future.
+ */
+static void mpc5125_twr_fec2_usb_iopad_init(void __iomem *ioctl, int isusb)
+{
+ int i;
+ const u8 offset[12] = {
+ IOCTL_USB1_DATA0, IOCTL_USB1_DATA1,
+ IOCTL_USB1_DATA2, IOCTL_USB1_DATA3,
+ IOCTL_USB1_DATA4, IOCTL_USB1_DATA5,
+ IOCTL_USB1_DATA6, IOCTL_USB1_DATA7,
+ IOCTL_USB1_STOP, IOCTL_USB1_CLK,
+ IOCTL_USB1_NEXT, IOCTL_USB1_DIR
+ };
+ u8 mode;
+
+ mode = (isusb) ? IOCTL_DEFAULT_MODE : IOCTL_FEC2_MODE;
+ for (i = 0; i < ARRAY_SIZE(offset); i++)
+ out_8(ioctl + offset[i], mode);
+}
+
+static void __init mpc5125_twr_setup_arch(void)
+{
+ struct device_node *np;
+
+ printk(KERN_INFO "TWR-MPC5125 board from Freescale Semiconductor\n");
+
+ /*
+ * io pad config
+ */
+ np = of_find_compatible_node(NULL, NULL, "fsl,mpc5125-ioctl");
+ if (np) {
+ void __iomem *ioctl = of_iomap(np, 0);
+
+ mpc5125_twr_fec2_usb_iopad_init(ioctl, 0);
+
+ of_node_put(np);
+ iounmap(ioctl);
+ }
+}
+
+static struct of_device_id __initdata of_bus_ids[] = {
+ { .name = "soc", },
+ {},
+};
+
+static void __init mpc5125_twr_declare_of_platform_devices(void)
+{
+ struct device_node *np;
+
+ if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
+ printk(KERN_ERR __FILE__ ": "
+ "Error while probing of_platform bus\n");
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,mpc5125-nfc");
+ if (np) {
+ of_platform_device_create(np, NULL, NULL);
+ of_node_put(np);
+ }
+}
+
+static void __init mpc5125_twr_init(void)
+{
+ mpc5125_twr_declare_of_platform_devices();
+ mpc5121_clk_init();
+ mpc512x_restart_init();
+ mpc512x_psc_fifo_init();
+}
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init mpc5125_twr_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "fsl,mpc5125ads");
+}
+
+define_machine(mpc5125_twr) {
+ .name = "TWR-MPC5125",
+ .probe = mpc5125_twr_probe,
+ .setup_arch = mpc5125_twr_setup_arch,
+ .init = mpc5125_twr_init,
+ .init_IRQ = mpc512x_init_IRQ,
+ .get_irq = ipic_get_irq,
+ .calibrate_decr = generic_calibrate_decr,
+ .restart = mpc512x_restart,
+};
diff --git a/arch/powerpc/platforms/512x/mpc512x.h
b/arch/powerpc/platforms/512x/mpc512x.h
index 1ab6d11..91c903f 100644
--- a/arch/powerpc/platforms/512x/mpc512x.h
+++ b/arch/powerpc/platforms/512x/mpc512x.h
@@ -13,8 +13,11 @@
#define __MPC512X_H__
extern void __init mpc512x_init_IRQ(void);
extern void __init mpc512x_init(void);
+extern void __init mpc512x_restart_init(void);
extern int __init mpc5121_clk_init(void);
-void __init mpc512x_declare_of_platform_devices(void);
+extern void __init mpc512x_declare_of_platform_devices(void);
+extern void __init mpc512x_psc_fifo_init(void);
+extern char *mpc512x_select_psc_compat(void);
extern void mpc512x_restart(char *cmd);
extern void mpc512x_init_diu(void);
extern void mpc512x_setup_diu(void);
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c
b/arch/powerpc/platforms/512x/mpc512x_shared.c
index e41ebbd..e79d8ae 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -32,7 +32,7 @@
static struct mpc512x_reset_module __iomem *reset_module_base;
-static void __init mpc512x_restart_init(void)
+void __init mpc512x_restart_init(void)
{
struct device_node *np;
@@ -382,6 +382,21 @@ void __init mpc512x_declare_of_platform_devices(void)
#define DEFAULT_FIFO_SIZE 16
+char *mpc512x_select_psc_compat(void)
+{
+ char *psc_compats[] = {
+ "fsl,mpc5121-psc",
+ "fsl,mpc5125-psc"
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(psc_compats); i++)
+ if (of_find_compatible_node(NULL, NULL, psc_compats[i]))
+ return psc_compats[i];
+
+ return NULL;
+}
+
static unsigned int __init get_fifo_size(struct device_node *np,
char *prop_name)
{
@@ -407,9 +422,16 @@ void __init mpc512x_psc_fifo_init(void)
void __iomem *psc;
unsigned int tx_fifo_size;
unsigned int rx_fifo_size;
+ char *psc_compat;
int fifobase = 0; /* current fifo address in 32 bit words */
- for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") {
+ psc_compat = mpc512x_select_psc_compat();
+ if (!psc_compat) {
+ pr_err("%s: no compatible devices found\n", __func__);
+ return;
+ }
+
+ for_each_compatible_node(np, NULL, psc_compat) {
tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size");
rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size");
--
1.7.1
^ permalink raw reply related
* Booting with ramdisk in kernel
From: Guillaume Dargaud @ 2011-03-22 11:04 UTC (permalink / raw)
To: linuxppc-dev
Hello all,
I already posted this on the buildroot mailing list, so apologies for the dupe, but maybe it's more relevant here.
I'm trying to do something very classic, but it doesn't seem to work and the more I read about it the more I'm confused
by the amount of antiquated info and nearly-but-not-quite-so relevant info (like doing a temporary ramdisk before the
'real' OS loads).
So I have a kernel and a buildroot-generated OS, currently on an NFS server. I boot with the following kernel parameters
and everything goes fine:
console=ttyUL0,115200 rw root=/dev/nfs ip=bootp
Now I want to embed that OS in the kernel (no need for a network anymore as the kernel is on a flash mem and I wrote my
own bootloader). So I did the following:
- add ROOTFS CPIO to the buildroot options and make a new version
- point CONFIG_INITRAMFS_SOURCE to the resulting rootfs.cpio file
- change the kernel parameters to "console=ttyUL0,115200 root=/dev/ram" (that's in a dts file)
- some documentation talks about CONFIG_BLK_DEV_RAM but I can't find that option in the menuconfig, so maybe that's the
problem.
When my bootloader jumps to 0x400000, the kernel stops instantly without even a blip on the console. A debugger reveals
that it stops at 0x401718... I have no idea what's going on at this stage.
What am I doing wrong ?
--
Guillaume Dargaud
http://www.gdargaud.net/
^ permalink raw reply
* Re: [PATCH v6 6/6] powerpc, tqm5200: update tqm5200_defconfig to fit for charon board.
From: Wolfram Sang @ 2011-03-22 9:10 UTC (permalink / raw)
To: Heiko Schocher
Cc: Ben Dooks, linux-fbdev, devicetree-discuss, Samuel Ortiz,
Vincent Sanders, linux-kernel, Randy Dunlap, Paul Mundt,
linuxppc-dev, Wolfgang Denk
In-Reply-To: <1300782452-528-7-git-send-email-hs@denx.de>
[-- Attachment #1: Type: text/plain, Size: 719 bytes --]
> As this board is tqm5200 based, added necessary changes
> to the tqm5200_defconfig. In previous patchserie I added
> the changes to mpc5200_defconfig, as Wolfram Sang mentioned,
> but as tqm5200_defconfig is in mainline, and the board is
> tqm5200 based, I think, thats the appropriate place, as
I'd think the perfect solution would have been to merge the
tqm-defconfig into the mpc5200-defconfig entirely and get rid of it.
That being said, I don't think this issue is big enough to block this
series, so fine enough with me.
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH v1 1/6] powerpc, 5200: add support for charon board
From: Wolfram Sang @ 2011-03-22 9:06 UTC (permalink / raw)
To: Heiko Schocher
Cc: Ben Dooks, linux-fbdev, devicetree-discuss, Samuel Ortiz,
Vincent Sanders, linux-kernel, Randy Dunlap, Paul Mundt,
linuxppc-dev, Wolfgang Denk
In-Reply-To: <1300782452-528-2-git-send-email-hs@denx.de>
[-- Attachment #1: Type: text/plain, Size: 1526 bytes --]
On Tue, Mar 22, 2011 at 09:27:27AM +0100, Heiko Schocher wrote:
> Signed-off-by: Heiko Schocher <hs@denx.de>
> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> cc: Wolfram Sang <w.sang@pengutronix.de>
> cc: Grant Likely <grant.likely@secretlab.ca>
> cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> cc: linux-fbdev@vger.kernel.org
> cc: devicetree-discuss@ozlabs.org
> cc: Ben Dooks <ben@simtec.co.uk>
> cc: Vincent Sanders <vince@simtec.co.uk>
> cc: Samuel Ortiz <sameo@linux.intel.com>
> cc: linux-kernel@vger.kernel.org
> cc: Randy Dunlap <rdunlap@xenotime.net>
> cc: Wolfgang Denk <wd@denx.de>
> cc: Paul Mundt <lethal@linux-sh.org>
> ---
> - changes since v1:
> add comments from Wolfram Sang
> - no defconfig file
> - comment corrected in DTS
> - boardlist sorted alphabetically
> - commit log without boardinfo
> - changes for v6:
> - rebased against current head
> - repost complete patchserie
> - added Acked-by from Benjamin Herrenschmidt
>
> arch/powerpc/boot/dts/charon.dts | 226 ++++++++++++++++++++++++++
> arch/powerpc/platforms/52xx/mpc5200_simple.c | 1 +
> 2 files changed, 227 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/boot/dts/charon.dts
AFAICR all my concerns have been addressed, so
Acked-by: Wolfram Sang <w.sang@pengutronix.de>
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* [PATCH v1 1/6] powerpc, 5200: add support for charon board
From: Heiko Schocher @ 2011-03-22 8:27 UTC (permalink / raw)
To: linuxppc-dev
Cc: Ben Dooks, linux-fbdev, devicetree-discuss, Samuel Ortiz,
Vincent Sanders, linux-kernel, Randy Dunlap, Paul Mundt,
Heiko Schocher, Wolfgang Denk
In-Reply-To: <1300782452-528-1-git-send-email-hs@denx.de>
Signed-off-by: Heiko Schocher <hs@denx.de>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
cc: Wolfram Sang <w.sang@pengutronix.de>
cc: Grant Likely <grant.likely@secretlab.ca>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Wolfgang Denk <wd@denx.de>
cc: Paul Mundt <lethal@linux-sh.org>
---
- changes since v1:
add comments from Wolfram Sang
- no defconfig file
- comment corrected in DTS
- boardlist sorted alphabetically
- commit log without boardinfo
- changes for v6:
- rebased against current head
- repost complete patchserie
- added Acked-by from Benjamin Herrenschmidt
arch/powerpc/boot/dts/charon.dts | 226 ++++++++++++++++++++++++++
arch/powerpc/platforms/52xx/mpc5200_simple.c | 1 +
2 files changed, 227 insertions(+), 0 deletions(-)
create mode 100644 arch/powerpc/boot/dts/charon.dts
diff --git a/arch/powerpc/boot/dts/charon.dts b/arch/powerpc/boot/dts/charon.dts
new file mode 100644
index 0000000..9776889
--- /dev/null
+++ b/arch/powerpc/boot/dts/charon.dts
@@ -0,0 +1,226 @@
+/*
+ * charon board Device Tree Source
+ *
+ * Copyright (C) 2007 Semihalf
+ * Marian Balakowicz <m8@semihalf.com>
+ *
+ * Copyright (C) 2010 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@denx.de>
+ *
+ * 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 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "anon,charon";
+ compatible = "anon,charon";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,5200@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>; // from bootloader
+ bus-frequency = <0>; // from bootloader
+ clock-frequency = <0>; // from bootloader
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x08000000>; // 128MB
+ };
+
+ soc5200@f0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc5200-immr";
+ ranges = <0 0xf0000000 0x0000c000>;
+ reg = <0xf0000000 0x00000100>;
+ bus-frequency = <0>; // from bootloader
+ system-frequency = <0>; // from bootloader
+
+ cdm@200 {
+ compatible = "fsl,mpc5200-cdm";
+ reg = <0x200 0x38>;
+ };
+
+ mpc5200_pic: interrupt-controller@500 {
+ // 5200 interrupts are encoded into two levels;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ compatible = "fsl,mpc5200-pic";
+ reg = <0x500 0x80>;
+ };
+
+ timer@600 { // General Purpose Timer
+ compatible = "fsl,mpc5200-gpt";
+ reg = <0x600 0x10>;
+ interrupts = <1 9 0>;
+ fsl,has-wdt;
+ };
+
+ can@900 {
+ compatible = "fsl,mpc5200-mscan";
+ interrupts = <2 17 0>;
+ reg = <0x900 0x80>;
+ };
+
+ can@980 {
+ compatible = "fsl,mpc5200-mscan";
+ interrupts = <2 18 0>;
+ reg = <0x980 0x80>;
+ };
+
+ gpio_simple: gpio@b00 {
+ compatible = "fsl,mpc5200-gpio";
+ reg = <0xb00 0x40>;
+ interrupts = <1 7 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ usb@1000 {
+ compatible = "fsl,mpc5200-ohci","ohci-be";
+ reg = <0x1000 0xff>;
+ interrupts = <2 6 0>;
+ };
+
+ dma-controller@1200 {
+ device_type = "dma-controller";
+ compatible = "fsl,mpc5200-bestcomm";
+ reg = <0x1200 0x80>;
+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
+ 3 4 0 3 5 0 3 6 0 3 7 0
+ 3 8 0 3 9 0 3 10 0 3 11 0
+ 3 12 0 3 13 0 3 14 0 3 15 0>;
+ };
+
+ xlb@1f00 {
+ compatible = "fsl,mpc5200-xlb";
+ reg = <0x1f00 0x100>;
+ };
+
+ serial@2000 { // PSC1
+ compatible = "fsl,mpc5200-psc-uart";
+ reg = <0x2000 0x100>;
+ interrupts = <2 1 0>;
+ };
+
+ serial@2400 { // PSC3
+ compatible = "fsl,mpc5200-psc-uart";
+ reg = <0x2400 0x100>;
+ interrupts = <2 3 0>;
+ };
+
+ ethernet@3000 {
+ compatible = "fsl,mpc5200-fec";
+ reg = <0x3000 0x400>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <2 5 0>;
+ fixed-link = <1 1 100 0 0>;
+ };
+
+ mdio@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200-mdio";
+ reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
+ interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
+ };
+
+ ata@3a00 {
+ compatible = "fsl,mpc5200-ata";
+ reg = <0x3a00 0x100>;
+ interrupts = <2 7 0>;
+ };
+
+ i2c@3d00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d00 0x40>;
+ interrupts = <2 15 0>;
+ };
+
+
+ i2c@3d40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d40 0x40>;
+ interrupts = <2 16 0>;
+
+ dtt@28 {
+ compatible = "national,lm80";
+ reg = <0x28>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ };
+ };
+
+ sram@8000 {
+ compatible = "fsl,mpc5200-sram";
+ reg = <0x8000 0x4000>;
+ };
+ };
+
+ localbus {
+ compatible = "fsl,mpc5200-lpb","simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = < 0 0 0xfc000000 0x02000000
+ 3 0 0xe8000000 0x00080000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+ };
+
+ mram0@3,0 {
+ compatible = "mtd-ram";
+ reg = <3 0x00000 0x80000>;
+ bank-width = <1>;
+ };
+ };
+
+ pci@f0000d00 {
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ compatible = "fsl,mpc5200-pci";
+ reg = <0xf0000d00 0x100>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3
+ 0xc000 0 0 2 &mpc5200_pic 0 0 3
+ 0xc000 0 0 3 &mpc5200_pic 0 0 3
+ 0xc000 0 0 4 &mpc5200_pic 0 0 3>;
+ clock-frequency = <0>; // From boot loader
+ interrupts = <2 8 0 2 9 0 2 10 0>;
+ bus-range = <0 0>;
+ ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
+ 0x02000000 0 0x90000000 0x90000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xa0000000 0 0x01000000>;
+ };
+};
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c
index e36d6e2..846b789 100644
--- a/arch/powerpc/platforms/52xx/mpc5200_simple.c
+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c
@@ -50,6 +50,7 @@ static void __init mpc5200_simple_setup_arch(void)
/* list of the supported boards */
static const char *board[] __initdata = {
+ "anon,charon",
"intercontrol,digsy-mtc",
"manroland,mucmc52",
"manroland,uc101",
--
1.7.4
^ permalink raw reply related
* [PATCH v6 4/6] video, sm501: add OF binding to support SM501
From: Heiko Schocher @ 2011-03-22 8:27 UTC (permalink / raw)
To: linuxppc-dev
Cc: Ben Dooks, linux-fbdev, devicetree-discuss, Samuel Ortiz,
Vincent Sanders, linux-kernel, Randy Dunlap, Paul Mundt,
Heiko Schocher, Wolfgang Denk
In-Reply-To: <1300782452-528-1-git-send-email-hs@denx.de>
- add binding to OF, compatible name "smi,sm501"
Signed-off-by: Heiko Schocher <hs@denx.de>
Acked-by: Samuel Ortiz <sameo@linux.intel.com>
cc: Wolfram Sang <w.sang@pengutronix.de>
cc: Grant Likely <grant.likely@secretlab.ca>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Wolfgang Denk <wd@denx.de>
cc: Paul Mundt <lethal@linux-sh.org>
---
- changes since v1:
add Ben Dooks, Vincent Sanders and Samuel Ortiz to cc, as suggested from
Paul Mundt.
- changes since v2:
add comments from Randy Dunlap:
- move parameter documentation to Documentation/fb/sm501.txt
- changes since v3:
- rebased against v2.6.38-rc2
- split in 3 patches
- of support patch
- get rid of "#if defined(CONFIG_PPC_MPC52xx)" usage
hide this in DTS, as Paul suggested.
- i/o routine patch
- edid support patch
- changes since v4
replace remaining CONFIG_PPC_MPC52xx with CONFIG_OF, as
it is no longer MPC52xx only.
- changes since v5
free edid_data after its usage, as it is no longer needed,
suggested from Paul Mundt. Also fall back to default if
kmemdup(edid_data) fails.
- changes for v6:
- repost complete patchserie
- rebased against current head
Documentation/powerpc/dts-bindings/sm501.txt | 34 +++++++++++++++++++++++++
drivers/mfd/sm501.c | 8 +++++-
drivers/video/sm501fb.c | 35 +++++++++++++++++++++++++-
3 files changed, 75 insertions(+), 2 deletions(-)
create mode 100644 Documentation/powerpc/dts-bindings/sm501.txt
diff --git a/Documentation/powerpc/dts-bindings/sm501.txt b/Documentation/powerpc/dts-bindings/sm501.txt
new file mode 100644
index 0000000..7d319fb
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/sm501.txt
@@ -0,0 +1,34 @@
+* SM SM501
+
+The SM SM501 is a LCD controller, with proper hardware, it can also
+drive DVI monitors.
+
+Required properties:
+- compatible : should be "smi,sm501".
+- reg : contain two entries:
+ - First entry: System Configuration register
+ - Second entry: IO space (Display Controller register)
+- interrupts : SMI interrupt to the cpu should be described here.
+- interrupt-parent : the phandle for the interrupt controller that
+ services interrupts for this device.
+
+Optional properties:
+- mode : select a video mode:
+ <xres>x<yres>[-<bpp>][@<refresh>]
+- edid : verbatim EDID data block describing attached display.
+ Data from the detailed timing descriptor will be used to
+ program the display controller.
+- little-endian: availiable on big endian systems, to
+ set different foreign endian.
+- big-endian: availiable on little endian systems, to
+ set different foreign endian.
+
+Example for MPC5200:
+ display@1,0 {
+ compatible = "smi,sm501";
+ reg = <1 0x00000000 0x00800000
+ 1 0x03e00000 0x00200000>;
+ interrupts = <1 1 3>;
+ mode = "640x480-32@60";
+ edid = [edid-data];
+ };
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 558d5f3..574f696 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1377,7 +1377,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
sm501_register_gpio(sm);
}
- if (pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
+ if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
if (!sm501_gpio_isregistered(sm))
dev_err(sm->dev, "no gpio available for i2c gpio.\n");
else
@@ -1735,10 +1735,16 @@ static struct pci_driver sm501_pci_driver = {
MODULE_ALIAS("platform:sm501");
+static struct of_device_id __devinitdata of_sm501_match_tbl[] = {
+ { .compatible = "smi,sm501", },
+ { /* end */ }
+};
+
static struct platform_driver sm501_plat_driver = {
.driver = {
.name = "sm501",
.owner = THIS_MODULE,
+ .of_match_table = of_sm501_match_tbl,
},
.probe = sm501_plat_probe,
.remove = sm501_plat_remove,
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index f31252c..f275385 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -1729,6 +1729,15 @@ static int sm501fb_init_fb(struct fb_info *fb,
FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
+#if defined(CONFIG_OF)
+#ifdef __BIG_ENDIAN
+ if (of_get_property(info->dev->parent->of_node, "little-endian", NULL))
+ fb->flags |= FBINFO_FOREIGN_ENDIAN;
+#else
+ if (of_get_property(info->dev->parent->of_node, "big-endian", NULL))
+ fb->flags |= FBINFO_FOREIGN_ENDIAN;
+#endif
+#endif
/* fixed data */
fb->fix.type = FB_TYPE_PACKED_PIXELS;
@@ -1933,8 +1942,32 @@ static int __devinit sm501fb_probe(struct platform_device *pdev)
}
if (info->pdata == NULL) {
- dev_info(dev, "using default configuration data\n");
+ int found = 0;
+#if defined(CONFIG_OF)
+ struct device_node *np = pdev->dev.parent->of_node;
+ const u8 *prop;
+ const char *cp;
+ int len;
+
info->pdata = &sm501fb_def_pdata;
+ if (np) {
+ /* Get EDID */
+ cp = of_get_property(np, "mode", &len);
+ if (cp)
+ strcpy(fb_mode, cp);
+ prop = of_get_property(np, "edid", &len);
+ if (prop && len == EDID_LENGTH) {
+ info->edid_data = kmemdup(prop, EDID_LENGTH,
+ GFP_KERNEL);
+ if (info->edid_data)
+ found = 1;
+ }
+ }
+#endif
+ if (!found) {
+ dev_info(dev, "using default configuration data\n");
+ info->pdata = &sm501fb_def_pdata;
+ }
}
/* probe for the presence of each panel */
--
1.7.4
^ permalink raw reply related
* [PATCH v6 5/6] powerpc, video: add SM501 support for charon board.
From: Heiko Schocher @ 2011-03-22 8:27 UTC (permalink / raw)
To: linuxppc-dev
Cc: Ben Dooks, linux-fbdev, devicetree-discuss, Samuel Ortiz,
Vincent Sanders, linux-kernel, Randy Dunlap, Paul Mundt,
Heiko Schocher, Wolfgang Denk
In-Reply-To: <1300782452-528-1-git-send-email-hs@denx.de>
Signed-off-by: Heiko Schocher <hs@denx.de>
cc: Wolfram Sang <w.sang@pengutronix.de>
cc: Grant Likely <grant.likely@secretlab.ca>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Wolfgang Denk <wd@denx.de>
cc: Paul Mundt <lethal@linux-sh.org>
---
- changes since v1:
- no board specific defconfig file for mpc52xx based boards as suggested
from Wolfram Sang
- changes since v2:
add Ben Dooks, Vincent Sanders and Samuel Ortiz and lkml to cc, as
suggested from Paul Mundt.
- changes since v3:
- rebased against v2.6.38-rc2
- changes since v4:
- added Paul Mundt to cc (Sorry forgot this in series v4)
arch/powerpc/boot/dts/charon.dts | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/dts/charon.dts b/arch/powerpc/boot/dts/charon.dts
index 9776889..0e00e50 100644
--- a/arch/powerpc/boot/dts/charon.dts
+++ b/arch/powerpc/boot/dts/charon.dts
@@ -186,6 +186,7 @@
#address-cells = <2>;
#size-cells = <1>;
ranges = < 0 0 0xfc000000 0x02000000
+ 1 0 0xe0000000 0x04000000 // CS1 range, SM501
3 0 0xe8000000 0x00080000>;
flash@0,0 {
@@ -197,6 +198,15 @@
#address-cells = <1>;
};
+ display@1,0 {
+ compatible = "smi,sm501";
+ reg = <1 0x00000000 0x00800000
+ 1 0x03e00000 0x00200000>;
+ mode = "640x480-32@60";
+ interrupts = <1 1 3>;
+ little-endian;
+ };
+
mram0@3,0 {
compatible = "mtd-ram";
reg = <3 0x00000 0x80000>;
--
1.7.4
^ permalink raw reply related
* [PATCH v6 2/6] video, sm501: add I/O functions for use on powerpc
From: Heiko Schocher @ 2011-03-22 8:27 UTC (permalink / raw)
To: linuxppc-dev
Cc: Ben Dooks, linux-fbdev, devicetree-discuss, Samuel Ortiz,
Vincent Sanders, linux-kernel, Randy Dunlap, Paul Mundt,
Heiko Schocher, Wolfgang Denk
In-Reply-To: <1300782452-528-1-git-send-email-hs@denx.de>
- add read/write functions for using this driver
also on powerpc plattforms
Signed-off-by: Heiko Schocher <hs@denx.de>
Acked-by: Samuel Ortiz <sameo@linux.intel.com>
cc: Wolfram Sang <w.sang@pengutronix.de>
cc: Grant Likely <grant.likely@secretlab.ca>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Wolfgang Denk <wd@denx.de>
cc: Paul Mundt <lethal@linux-sh.org>
---
- changes since v1:
add Ben Dooks, Vincent Sanders and Samuel Ortiz to cc, as suggested from
Paul Mundt.
- changes since v2:
add comments from Randy Dunlap:
- move parameter documentation to Documentation/fb/sm501.txt
- changes since v3:
- rebased against v2.6.38-rc2
- split in 3 patches
- of support patch
- i/o routine patch
- use ioread/write32{be} accessors instead of
__do_readl/__do_writel{_be}
- edid support patch
- changes for v6:
- repost complete patchserie
- rebased against current head
drivers/mfd/sm501.c | 125 +++++++++++++++++-----------------
drivers/video/sm501fb.c | 172 ++++++++++++++++++++++++----------------------
include/linux/sm501.h | 8 ++
3 files changed, 161 insertions(+), 144 deletions(-)
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 5de3a76..558d5f3 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -133,10 +133,10 @@ static unsigned long decode_div(unsigned long pll2, unsigned long val,
static void sm501_dump_clk(struct sm501_devdata *sm)
{
- unsigned long misct = readl(sm->regs + SM501_MISC_TIMING);
- unsigned long pm0 = readl(sm->regs + SM501_POWER_MODE_0_CLOCK);
- unsigned long pm1 = readl(sm->regs + SM501_POWER_MODE_1_CLOCK);
- unsigned long pmc = readl(sm->regs + SM501_POWER_MODE_CONTROL);
+ unsigned long misct = smc501_readl(sm->regs + SM501_MISC_TIMING);
+ unsigned long pm0 = smc501_readl(sm->regs + SM501_POWER_MODE_0_CLOCK);
+ unsigned long pm1 = smc501_readl(sm->regs + SM501_POWER_MODE_1_CLOCK);
+ unsigned long pmc = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
unsigned long sdclk0, sdclk1;
unsigned long pll2 = 0;
@@ -193,29 +193,29 @@ static void sm501_dump_regs(struct sm501_devdata *sm)
void __iomem *regs = sm->regs;
dev_info(sm->dev, "System Control %08x\n",
- readl(regs + SM501_SYSTEM_CONTROL));
+ smc501_readl(regs + SM501_SYSTEM_CONTROL));
dev_info(sm->dev, "Misc Control %08x\n",
- readl(regs + SM501_MISC_CONTROL));
+ smc501_readl(regs + SM501_MISC_CONTROL));
dev_info(sm->dev, "GPIO Control Low %08x\n",
- readl(regs + SM501_GPIO31_0_CONTROL));
+ smc501_readl(regs + SM501_GPIO31_0_CONTROL));
dev_info(sm->dev, "GPIO Control Hi %08x\n",
- readl(regs + SM501_GPIO63_32_CONTROL));
+ smc501_readl(regs + SM501_GPIO63_32_CONTROL));
dev_info(sm->dev, "DRAM Control %08x\n",
- readl(regs + SM501_DRAM_CONTROL));
+ smc501_readl(regs + SM501_DRAM_CONTROL));
dev_info(sm->dev, "Arbitration Ctrl %08x\n",
- readl(regs + SM501_ARBTRTN_CONTROL));
+ smc501_readl(regs + SM501_ARBTRTN_CONTROL));
dev_info(sm->dev, "Misc Timing %08x\n",
- readl(regs + SM501_MISC_TIMING));
+ smc501_readl(regs + SM501_MISC_TIMING));
}
static void sm501_dump_gate(struct sm501_devdata *sm)
{
dev_info(sm->dev, "CurrentGate %08x\n",
- readl(sm->regs + SM501_CURRENT_GATE));
+ smc501_readl(sm->regs + SM501_CURRENT_GATE));
dev_info(sm->dev, "CurrentClock %08x\n",
- readl(sm->regs + SM501_CURRENT_CLOCK));
+ smc501_readl(sm->regs + SM501_CURRENT_CLOCK));
dev_info(sm->dev, "PowerModeControl %08x\n",
- readl(sm->regs + SM501_POWER_MODE_CONTROL));
+ smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL));
}
#else
@@ -231,7 +231,7 @@ static inline void sm501_dump_clk(struct sm501_devdata *sm) { }
static void sm501_sync_regs(struct sm501_devdata *sm)
{
- readl(sm->regs);
+ smc501_readl(sm->regs);
}
static inline void sm501_mdelay(struct sm501_devdata *sm, unsigned int delay)
@@ -261,11 +261,11 @@ int sm501_misc_control(struct device *dev,
spin_lock_irqsave(&sm->reg_lock, save);
- misc = readl(sm->regs + SM501_MISC_CONTROL);
+ misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
to = (misc & ~clear) | set;
if (to != misc) {
- writel(to, sm->regs + SM501_MISC_CONTROL);
+ smc501_writel(to, sm->regs + SM501_MISC_CONTROL);
sm501_sync_regs(sm);
dev_dbg(sm->dev, "MISC_CONTROL %08lx\n", misc);
@@ -294,11 +294,11 @@ unsigned long sm501_modify_reg(struct device *dev,
spin_lock_irqsave(&sm->reg_lock, save);
- data = readl(sm->regs + reg);
+ data = smc501_readl(sm->regs + reg);
data |= set;
data &= ~clear;
- writel(data, sm->regs + reg);
+ smc501_writel(data, sm->regs + reg);
sm501_sync_regs(sm);
spin_unlock_irqrestore(&sm->reg_lock, save);
@@ -322,9 +322,9 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
mutex_lock(&sm->clock_lock);
- mode = readl(sm->regs + SM501_POWER_MODE_CONTROL);
- gate = readl(sm->regs + SM501_CURRENT_GATE);
- clock = readl(sm->regs + SM501_CURRENT_CLOCK);
+ mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
+ gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
+ clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
mode &= 3; /* get current power mode */
@@ -356,14 +356,14 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
switch (mode) {
case 1:
- writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
- writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
+ smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
+ smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
mode = 0;
break;
case 2:
case 0:
- writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
- writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
+ smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
+ smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
mode = 1;
break;
@@ -372,7 +372,7 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
goto already;
}
- writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
+ smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
sm501_sync_regs(sm);
dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
@@ -519,9 +519,9 @@ unsigned long sm501_set_clock(struct device *dev,
unsigned long req_freq)
{
struct sm501_devdata *sm = dev_get_drvdata(dev);
- unsigned long mode = readl(sm->regs + SM501_POWER_MODE_CONTROL);
- unsigned long gate = readl(sm->regs + SM501_CURRENT_GATE);
- unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK);
+ unsigned long mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
+ unsigned long gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
+ unsigned long clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
unsigned char reg;
unsigned int pll_reg = 0;
unsigned long sm501_freq; /* the actual frequency achieved */
@@ -592,9 +592,9 @@ unsigned long sm501_set_clock(struct device *dev,
mutex_lock(&sm->clock_lock);
- mode = readl(sm->regs + SM501_POWER_MODE_CONTROL);
- gate = readl(sm->regs + SM501_CURRENT_GATE);
- clock = readl(sm->regs + SM501_CURRENT_CLOCK);
+ mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
+ gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
+ clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
clock = clock & ~(0xFF << clksrc);
clock |= reg<<clksrc;
@@ -603,14 +603,14 @@ unsigned long sm501_set_clock(struct device *dev,
switch (mode) {
case 1:
- writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
- writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
+ smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
+ smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
mode = 0;
break;
case 2:
case 0:
- writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
- writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
+ smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
+ smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
mode = 1;
break;
@@ -619,10 +619,11 @@ unsigned long sm501_set_clock(struct device *dev,
return -1;
}
- writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
+ smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
if (pll_reg)
- writel(pll_reg, sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL);
+ smc501_writel(pll_reg,
+ sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL);
sm501_sync_regs(sm);
@@ -902,7 +903,7 @@ static int sm501_gpio_get(struct gpio_chip *chip, unsigned offset)
struct sm501_gpio_chip *smgpio = to_sm501_gpio(chip);
unsigned long result;
- result = readl(smgpio->regbase + SM501_GPIO_DATA_LOW);
+ result = smc501_readl(smgpio->regbase + SM501_GPIO_DATA_LOW);
result >>= offset;
return result & 1UL;
@@ -915,13 +916,13 @@ static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip,
/* check and modify if this pin is not set as gpio. */
- if (readl(smchip->control) & bit) {
+ if (smc501_readl(smchip->control) & bit) {
dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev,
"changing mode of gpio, bit %08lx\n", bit);
- ctrl = readl(smchip->control);
+ ctrl = smc501_readl(smchip->control);
ctrl &= ~bit;
- writel(ctrl, smchip->control);
+ smc501_writel(ctrl, smchip->control);
sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio));
}
@@ -942,10 +943,10 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
spin_lock_irqsave(&smgpio->lock, save);
- val = readl(regs + SM501_GPIO_DATA_LOW) & ~bit;
+ val = smc501_readl(regs + SM501_GPIO_DATA_LOW) & ~bit;
if (value)
val |= bit;
- writel(val, regs);
+ smc501_writel(val, regs);
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
sm501_gpio_ensure_gpio(smchip, bit);
@@ -967,8 +968,8 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
spin_lock_irqsave(&smgpio->lock, save);
- ddr = readl(regs + SM501_GPIO_DDR_LOW);
- writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW);
+ ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
+ smc501_writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW);
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
sm501_gpio_ensure_gpio(smchip, bit);
@@ -994,18 +995,18 @@ static int sm501_gpio_output(struct gpio_chip *chip,
spin_lock_irqsave(&smgpio->lock, save);
- val = readl(regs + SM501_GPIO_DATA_LOW);
+ val = smc501_readl(regs + SM501_GPIO_DATA_LOW);
if (value)
val |= bit;
else
val &= ~bit;
- writel(val, regs);
+ smc501_writel(val, regs);
- ddr = readl(regs + SM501_GPIO_DDR_LOW);
- writel(ddr | bit, regs + SM501_GPIO_DDR_LOW);
+ ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
+ smc501_writel(ddr | bit, regs + SM501_GPIO_DDR_LOW);
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
- writel(val, regs + SM501_GPIO_DATA_LOW);
+ smc501_writel(val, regs + SM501_GPIO_DATA_LOW);
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
spin_unlock_irqrestore(&smgpio->lock, save);
@@ -1231,7 +1232,7 @@ static ssize_t sm501_dbg_regs(struct device *dev,
for (reg = 0x00; reg < 0x70; reg += 4) {
ret = sprintf(ptr, "%08x = %08x\n",
- reg, readl(sm->regs + reg));
+ reg, smc501_readl(sm->regs + reg));
ptr += ret;
}
@@ -1255,10 +1256,10 @@ static inline void sm501_init_reg(struct sm501_devdata *sm,
{
unsigned long tmp;
- tmp = readl(sm->regs + reg);
+ tmp = smc501_readl(sm->regs + reg);
tmp &= ~r->mask;
tmp |= r->set;
- writel(tmp, sm->regs + reg);
+ smc501_writel(tmp, sm->regs + reg);
}
/* sm501_init_regs
@@ -1299,7 +1300,7 @@ static void sm501_init_regs(struct sm501_devdata *sm,
static int sm501_check_clocks(struct sm501_devdata *sm)
{
- unsigned long pwrmode = readl(sm->regs + SM501_CURRENT_CLOCK);
+ unsigned long pwrmode = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
unsigned long msrc = (pwrmode & SM501_POWERMODE_M_SRC);
unsigned long m1src = (pwrmode & SM501_POWERMODE_M1_SRC);
@@ -1334,7 +1335,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
INIT_LIST_HEAD(&sm->devices);
- devid = readl(sm->regs + SM501_DEVICEID);
+ devid = smc501_readl(sm->regs + SM501_DEVICEID);
if ((devid & SM501_DEVICEID_IDMASK) != SM501_DEVICEID_SM501) {
dev_err(sm->dev, "incorrect device id %08lx\n", devid);
@@ -1342,9 +1343,9 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
}
/* disable irqs */
- writel(0, sm->regs + SM501_IRQ_MASK);
+ smc501_writel(0, sm->regs + SM501_IRQ_MASK);
- dramctrl = readl(sm->regs + SM501_DRAM_CONTROL);
+ dramctrl = smc501_readl(sm->regs + SM501_DRAM_CONTROL);
mem_avail = sm501_mem_local[(dramctrl >> 13) & 0x7];
dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n",
@@ -1489,7 +1490,7 @@ static int sm501_plat_suspend(struct platform_device *pdev, pm_message_t state)
struct sm501_devdata *sm = platform_get_drvdata(pdev);
sm->in_suspend = 1;
- sm->pm_misc = readl(sm->regs + SM501_MISC_CONTROL);
+ sm->pm_misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
sm501_dump_regs(sm);
@@ -1513,9 +1514,9 @@ static int sm501_plat_resume(struct platform_device *pdev)
/* check to see if we are in the same state as when suspended */
- if (readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) {
+ if (smc501_readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) {
dev_info(sm->dev, "SM501_MISC_CONTROL changed over sleep\n");
- writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL);
+ smc501_writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL);
/* our suspend causes the controller state to change,
* either by something attempting setup, power loss,
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index bcb44a5..5df406c 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -117,7 +117,7 @@ static inline int v_total(struct fb_var_screeninfo *var)
static inline void sm501fb_sync_regs(struct sm501fb_info *info)
{
- readl(info->regs);
+ smc501_readl(info->regs);
}
/* sm501_alloc_mem
@@ -262,7 +262,7 @@ static void sm501fb_setup_gamma(struct sm501fb_info *fbi,
/* set gamma values */
for (offset = 0; offset < 256 * 4; offset += 4) {
- writel(value, fbi->regs + palette + offset);
+ smc501_writel(value, fbi->regs + palette + offset);
value += 0x010101; /* Advance RGB by 1,1,1.*/
}
}
@@ -476,7 +476,8 @@ static int sm501fb_set_par_common(struct fb_info *info,
/* set start of framebuffer to the screen */
- writel(par->screen.sm_addr | SM501_ADDR_FLIP, fbi->regs + head_addr);
+ smc501_writel(par->screen.sm_addr | SM501_ADDR_FLIP,
+ fbi->regs + head_addr);
/* program CRT clock */
@@ -519,7 +520,7 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
reg = info->fix.line_length;
reg |= ((var->xres * var->bits_per_pixel)/8) << 16;
- writel(reg, fbi->regs + (par->head == HEAD_CRT ?
+ smc501_writel(reg, fbi->regs + (par->head == HEAD_CRT ?
SM501_DC_CRT_FB_OFFSET : SM501_DC_PANEL_FB_OFFSET));
/* program horizontal total */
@@ -527,27 +528,27 @@ static void sm501fb_set_par_geometry(struct fb_info *info,
reg = (h_total(var) - 1) << 16;
reg |= (var->xres - 1);
- writel(reg, base + SM501_OFF_DC_H_TOT);
+ smc501_writel(reg, base + SM501_OFF_DC_H_TOT);
/* program horizontal sync */
reg = var->hsync_len << 16;
reg |= var->xres + var->right_margin - 1;
- writel(reg, base + SM501_OFF_DC_H_SYNC);
+ smc501_writel(reg, base + SM501_OFF_DC_H_SYNC);
/* program vertical total */
reg = (v_total(var) - 1) << 16;
reg |= (var->yres - 1);
- writel(reg, base + SM501_OFF_DC_V_TOT);
+ smc501_writel(reg, base + SM501_OFF_DC_V_TOT);
/* program vertical sync */
reg = var->vsync_len << 16;
reg |= var->yres + var->lower_margin - 1;
- writel(reg, base + SM501_OFF_DC_V_SYNC);
+ smc501_writel(reg, base + SM501_OFF_DC_V_SYNC);
}
/* sm501fb_pan_crt
@@ -566,15 +567,15 @@ static int sm501fb_pan_crt(struct fb_var_screeninfo *var,
xoffs = var->xoffset * bytes_pixel;
- reg = readl(fbi->regs + SM501_DC_CRT_CONTROL);
+ reg = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
reg &= ~SM501_DC_CRT_CONTROL_PIXEL_MASK;
reg |= ((xoffs & 15) / bytes_pixel) << 4;
- writel(reg, fbi->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(reg, fbi->regs + SM501_DC_CRT_CONTROL);
reg = (par->screen.sm_addr + xoffs +
var->yoffset * info->fix.line_length);
- writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR);
+ smc501_writel(reg | SM501_ADDR_FLIP, fbi->regs + SM501_DC_CRT_FB_ADDR);
sm501fb_sync_regs(fbi);
return 0;
@@ -593,10 +594,10 @@ static int sm501fb_pan_pnl(struct fb_var_screeninfo *var,
unsigned long reg;
reg = var->xoffset | (var->xres_virtual << 16);
- writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
+ smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_WIDTH);
reg = var->yoffset | (var->yres_virtual << 16);
- writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
+ smc501_writel(reg, fbi->regs + SM501_DC_PANEL_FB_HEIGHT);
sm501fb_sync_regs(fbi);
return 0;
@@ -622,7 +623,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
/* enable CRT DAC - note 0 is on!*/
sm501_misc_control(fbi->dev->parent, 0, SM501_MISC_DAC_POWER);
- control = readl(fbi->regs + SM501_DC_CRT_CONTROL);
+ control = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
control &= (SM501_DC_CRT_CONTROL_PIXEL_MASK |
SM501_DC_CRT_CONTROL_GAMMA |
@@ -684,7 +685,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)
out_update:
dev_dbg(fbi->dev, "new control is %08lx\n", control);
- writel(control, fbi->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(control, fbi->regs + SM501_DC_CRT_CONTROL);
sm501fb_sync_regs(fbi);
return 0;
@@ -696,18 +697,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL;
struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl;
- control = readl(ctrl_reg);
+ control = smc501_readl(ctrl_reg);
if (to && (control & SM501_DC_PANEL_CONTROL_VDD) == 0) {
/* enable panel power */
control |= SM501_DC_PANEL_CONTROL_VDD; /* FPVDDEN */
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
control |= SM501_DC_PANEL_CONTROL_DATA; /* DATA */
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
@@ -719,7 +720,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
else
control |= SM501_DC_PANEL_CONTROL_BIAS;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
}
@@ -730,7 +731,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
else
control |= SM501_DC_PANEL_CONTROL_FPEN;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
}
@@ -742,7 +743,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
else
control &= ~SM501_DC_PANEL_CONTROL_FPEN;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
}
@@ -753,18 +754,18 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
else
control &= ~SM501_DC_PANEL_CONTROL_BIAS;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
}
control &= ~SM501_DC_PANEL_CONTROL_DATA;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
control &= ~SM501_DC_PANEL_CONTROL_VDD;
- writel(control, ctrl_reg);
+ smc501_writel(control, ctrl_reg);
sm501fb_sync_regs(fbi);
mdelay(10);
}
@@ -799,7 +800,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
/* update control register */
- control = readl(fbi->regs + SM501_DC_PANEL_CONTROL);
+ control = smc501_readl(fbi->regs + SM501_DC_PANEL_CONTROL);
control &= (SM501_DC_PANEL_CONTROL_GAMMA |
SM501_DC_PANEL_CONTROL_VDD |
SM501_DC_PANEL_CONTROL_DATA |
@@ -833,16 +834,16 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
BUG();
}
- writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL);
+ smc501_writel(0x0, fbi->regs + SM501_DC_PANEL_PANNING_CONTROL);
/* panel plane top left and bottom right location */
- writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC);
+ smc501_writel(0x00, fbi->regs + SM501_DC_PANEL_TL_LOC);
reg = var->xres - 1;
reg |= (var->yres - 1) << 16;
- writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC);
+ smc501_writel(reg, fbi->regs + SM501_DC_PANEL_BR_LOC);
/* program panel control register */
@@ -855,7 +856,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
if ((var->sync & FB_SYNC_VERT_HIGH_ACT) == 0)
control |= SM501_DC_PANEL_CONTROL_VSP;
- writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
+ smc501_writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
sm501fb_sync_regs(fbi);
/* ensure the panel interface is not tristated at this point */
@@ -924,7 +925,7 @@ static int sm501fb_setcolreg(unsigned regno,
val |= (green >> 8) << 8;
val |= blue >> 8;
- writel(val, base + (regno * 4));
+ smc501_writel(val, base + (regno * 4));
}
break;
@@ -980,7 +981,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
dev_dbg(fbi->dev, "%s(mode=%d, %p)\n", __func__, blank_mode, info);
- ctrl = readl(fbi->regs + SM501_DC_CRT_CONTROL);
+ ctrl = smc501_readl(fbi->regs + SM501_DC_CRT_CONTROL);
switch (blank_mode) {
case FB_BLANK_POWERDOWN:
@@ -1004,7 +1005,7 @@ static int sm501fb_blank_crt(int blank_mode, struct fb_info *info)
}
- writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(ctrl, fbi->regs + SM501_DC_CRT_CONTROL);
sm501fb_sync_regs(fbi);
return 0;
@@ -1041,12 +1042,14 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
if (cursor->image.depth > 1)
return -EINVAL;
- hwc_addr = readl(base + SM501_OFF_HWC_ADDR);
+ hwc_addr = smc501_readl(base + SM501_OFF_HWC_ADDR);
if (cursor->enable)
- writel(hwc_addr | SM501_HWC_EN, base + SM501_OFF_HWC_ADDR);
+ smc501_writel(hwc_addr | SM501_HWC_EN,
+ base + SM501_OFF_HWC_ADDR);
else
- writel(hwc_addr & ~SM501_HWC_EN, base + SM501_OFF_HWC_ADDR);
+ smc501_writel(hwc_addr & ~SM501_HWC_EN,
+ base + SM501_OFF_HWC_ADDR);
/* set data */
if (cursor->set & FB_CUR_SETPOS) {
@@ -1060,7 +1063,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
//y += cursor->image.height;
- writel(x | (y << 16), base + SM501_OFF_HWC_LOC);
+ smc501_writel(x | (y << 16), base + SM501_OFF_HWC_LOC);
}
if (cursor->set & FB_CUR_SETCMAP) {
@@ -1080,8 +1083,8 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg);
- writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
- writel(fg, base + SM501_OFF_HWC_COLOR_3);
+ smc501_writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
+ smc501_writel(fg, base + SM501_OFF_HWC_COLOR_3);
}
if (cursor->set & FB_CUR_SETSIZE ||
@@ -1102,7 +1105,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
__func__, cursor->image.width, cursor->image.height);
for (op = 0; op < (64*64*2)/8; op+=4)
- writel(0x0, dst + op);
+ smc501_writel(0x0, dst + op);
for (y = 0; y < cursor->image.height; y++) {
for (x = 0; x < cursor->image.width; x++) {
@@ -1141,7 +1144,7 @@ static ssize_t sm501fb_crtsrc_show(struct device *dev,
struct sm501fb_info *info = dev_get_drvdata(dev);
unsigned long ctrl;
- ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
ctrl &= SM501_DC_CRT_CONTROL_SEL;
return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel");
@@ -1172,7 +1175,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
dev_info(dev, "setting crt source to head %d\n", head);
- ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
if (head == HEAD_CRT) {
ctrl |= SM501_DC_CRT_CONTROL_SEL;
@@ -1184,7 +1187,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,
ctrl &= ~SM501_DC_CRT_CONTROL_TE;
}
- writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
sm501fb_sync_regs(info);
return len;
@@ -1205,7 +1208,8 @@ static int sm501fb_show_regs(struct sm501fb_info *info, char *ptr,
unsigned int reg;
for (reg = start; reg < (len + start); reg += 4)
- ptr += sprintf(ptr, "%08x = %08x\n", reg, readl(mem + reg));
+ ptr += sprintf(ptr, "%08x = %08x\n", reg,
+ smc501_readl(mem + reg));
return ptr - buf;
}
@@ -1257,7 +1261,7 @@ static int sm501fb_sync(struct fb_info *info)
/* wait for the 2d engine to be ready */
while ((count > 0) &&
- (readl(fbi->regs + SM501_SYSTEM_CONTROL) &
+ (smc501_readl(fbi->regs + SM501_SYSTEM_CONTROL) &
SM501_SYSCTRL_2D_ENGINE_STATUS) != 0)
count--;
@@ -1312,45 +1316,46 @@ static void sm501fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
return;
/* set the base addresses */
- writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
- writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE);
+ smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
+ smc501_writel(par->screen.sm_addr,
+ fbi->regs2d + SM501_2D_DESTINATION_BASE);
/* set the window width */
- writel((info->var.xres << 16) | info->var.xres,
+ smc501_writel((info->var.xres << 16) | info->var.xres,
fbi->regs2d + SM501_2D_WINDOW_WIDTH);
/* set window stride */
- writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
+ smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
fbi->regs2d + SM501_2D_PITCH);
/* set data format */
switch (info->var.bits_per_pixel) {
case 8:
- writel(0, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
break;
case 16:
- writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
break;
case 32:
- writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
break;
}
/* 2d compare mask */
- writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
+ smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
/* 2d mask */
- writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
+ smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
/* source and destination x y */
- writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE);
- writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION);
+ smc501_writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE);
+ smc501_writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION);
/* w/h */
- writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
+ smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
/* do area move */
- writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL);
+ smc501_writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL);
}
static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
@@ -1372,47 +1377,49 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec
return;
/* set the base addresses */
- writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
- writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE);
+ smc501_writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE);
+ smc501_writel(par->screen.sm_addr,
+ fbi->regs2d + SM501_2D_DESTINATION_BASE);
/* set the window width */
- writel((info->var.xres << 16) | info->var.xres,
+ smc501_writel((info->var.xres << 16) | info->var.xres,
fbi->regs2d + SM501_2D_WINDOW_WIDTH);
/* set window stride */
- writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
+ smc501_writel((info->var.xres_virtual << 16) | info->var.xres_virtual,
fbi->regs2d + SM501_2D_PITCH);
/* set data format */
switch (info->var.bits_per_pixel) {
case 8:
- writel(0, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0, fbi->regs2d + SM501_2D_STRETCH);
break;
case 16:
- writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH);
break;
case 32:
- writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
+ smc501_writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH);
break;
}
/* 2d compare mask */
- writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
+ smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK);
/* 2d mask */
- writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
+ smc501_writel(0xffffffff, fbi->regs2d + SM501_2D_MASK);
/* colour */
- writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND);
+ smc501_writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND);
/* x y */
- writel((rect->dx << 16) | rect->dy, fbi->regs2d + SM501_2D_DESTINATION);
+ smc501_writel((rect->dx << 16) | rect->dy,
+ fbi->regs2d + SM501_2D_DESTINATION);
/* w/h */
- writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
+ smc501_writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION);
/* do rectangle fill */
- writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
+ smc501_writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL);
}
@@ -1470,11 +1477,12 @@ static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
/* initialise the colour registers */
- writel(par->cursor.sm_addr, par->cursor_regs + SM501_OFF_HWC_ADDR);
+ smc501_writel(par->cursor.sm_addr,
+ par->cursor_regs + SM501_OFF_HWC_ADDR);
- writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC);
- writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2);
- writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3);
+ smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_LOC);
+ smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_1_2);
+ smc501_writel(0x00, par->cursor_regs + SM501_OFF_HWC_COLOR_3);
sm501fb_sync_regs(info);
return 0;
@@ -1581,7 +1589,7 @@ static int sm501fb_start(struct sm501fb_info *info,
/* clear palette ram - undefined at power on */
for (k = 0; k < (256 * 3); k++)
- writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
+ smc501_writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
/* enable display controller */
sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1);
@@ -1649,20 +1657,20 @@ static int sm501fb_init_fb(struct fb_info *fb,
switch (head) {
case HEAD_CRT:
pd = info->pdata->fb_crt;
- ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
enable = (ctrl & SM501_DC_CRT_CONTROL_ENABLE) ? 1 : 0;
/* ensure we set the correct source register */
if (info->pdata->fb_route != SM501_FB_CRT_PANEL) {
ctrl |= SM501_DC_CRT_CONTROL_SEL;
- writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
}
break;
case HEAD_PANEL:
pd = info->pdata->fb_pnl;
- ctrl = readl(info->regs + SM501_DC_PANEL_CONTROL);
+ ctrl = smc501_readl(info->regs + SM501_DC_PANEL_CONTROL);
enable = (ctrl & SM501_DC_PANEL_CONTROL_EN) ? 1 : 0;
break;
@@ -1680,7 +1688,7 @@ static int sm501fb_init_fb(struct fb_info *fb,
if (head == HEAD_CRT && info->pdata->fb_route == SM501_FB_CRT_PANEL) {
ctrl &= ~SM501_DC_CRT_CONTROL_SEL;
- writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(ctrl, info->regs + SM501_DC_CRT_CONTROL);
enable = 0;
}
@@ -2085,7 +2093,7 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
struct sm501fb_info *info = platform_get_drvdata(pdev);
/* store crt control to resume with */
- info->pm_crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ info->pm_crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
sm501fb_suspend_fb(info, HEAD_CRT);
sm501fb_suspend_fb(info, HEAD_PANEL);
@@ -2109,10 +2117,10 @@ static int sm501fb_resume(struct platform_device *pdev)
/* restore the items we want to be saved for crt control */
- crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ crt_ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
crt_ctrl &= ~SM501_CRT_CTRL_SAVE;
crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE;
- writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
+ smc501_writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
sm501fb_resume_fb(info, HEAD_CRT);
sm501fb_resume_fb(info, HEAD_PANEL);
diff --git a/include/linux/sm501.h b/include/linux/sm501.h
index 214f932..02fde50 100644
--- a/include/linux/sm501.h
+++ b/include/linux/sm501.h
@@ -172,3 +172,11 @@ struct sm501_platdata {
struct sm501_platdata_gpio_i2c *gpio_i2c;
unsigned int gpio_i2c_nr;
};
+
+#if defined(CONFIG_PPC32)
+#define smc501_readl(addr) ioread32be((addr))
+#define smc501_writel(val, addr) iowrite32be((val), (addr))
+#else
+#define smc501_readl(addr) readl(addr)
+#define smc501_writel(val, addr) writel(val, addr)
+#endif
--
1.7.4
^ permalink raw reply related
* [PATCH v6 3/6] video, sm501: add edid and commandline support
From: Heiko Schocher @ 2011-03-22 8:27 UTC (permalink / raw)
To: linuxppc-dev
Cc: Ben Dooks, linux-fbdev, devicetree-discuss, Samuel Ortiz,
Vincent Sanders, linux-kernel, Randy Dunlap, Paul Mundt,
Heiko Schocher, Wolfgang Denk
In-Reply-To: <1300782452-528-1-git-send-email-hs@denx.de>
- add commandline options:
sm501fb.mode:
Specify resolution as "<xres>x<yres>[-<bpp>][@<refresh>]"
sm501fb.bpp:
Specify bit-per-pixel if not specified mode
- Add support for encoding display mode information
in the device tree using verbatim EDID block.
If the "edid" entry in the "smi,sm501" node is present,
the driver will build mode database using EDID data
and allow setting the display modes from this database.
Signed-off-by: Heiko Schocher <hs@denx.de>
cc: Wolfram Sang <w.sang@pengutronix.de>
cc: Grant Likely <grant.likely@secretlab.ca>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Wolfgang Denk <wd@denx.de>
cc: Paul Mundt <lethal@linux-sh.org>
---
- changes since v1:
add Ben Dooks, Vincent Sanders and Samuel Ortiz to cc, as suggested from
Paul Mundt.
- changes since v2:
add comments from Randy Dunlap:
- move parameter documentation to Documentation/fb/sm501.txt
- changes since v3:
- rebased against v2.6.38-rc2
- split in 3 patches
- of support patch
- i/o routine patch
- edid support patch
- changes since v4:
- add "info->pdata = &sm501fb_def_pdata;" in sm501fb_probe()
as Paul Mundt suggested (and I wrongly deleted)
- move kfree(info->edid_data); to patch 3/4
as edid_data is only allocated in the CONFIG_OF case
- changes for v6:
- repost complete patchserie
- rebased against current head
Documentation/fb/sm501.txt | 10 +++++++
drivers/video/sm501fb.c | 65 ++++++++++++++++++++++++++++++++++++++++---
2 files changed, 70 insertions(+), 5 deletions(-)
create mode 100644 Documentation/fb/sm501.txt
diff --git a/Documentation/fb/sm501.txt b/Documentation/fb/sm501.txt
new file mode 100644
index 0000000..8d17aeb
--- /dev/null
+++ b/Documentation/fb/sm501.txt
@@ -0,0 +1,10 @@
+Configuration:
+
+You can pass the following kernel command line options to sm501 videoframebuffer:
+
+ sm501fb.bpp= SM501 Display driver:
+ Specifiy bits-per-pixel if not specified by 'mode'
+
+ sm501fb.mode= SM501 Display driver:
+ Specify resolution as
+ "<xres>x<yres>[-<bpp>][@<refresh>]"
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 5df406c..f31252c 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -41,6 +41,26 @@
#include <linux/sm501.h>
#include <linux/sm501-regs.h>
+#include "edid.h"
+
+static char *fb_mode = "640x480-16@60";
+static unsigned long default_bpp = 16;
+
+static struct fb_videomode __devinitdata sm501_default_mode = {
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 20833,
+ .left_margin = 142,
+ .right_margin = 13,
+ .upper_margin = 21,
+ .lower_margin = 1,
+ .hsync_len = 69,
+ .vsync_len = 3,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED
+};
+
#define NR_PALETTE 256
enum sm501_controller {
@@ -77,6 +97,7 @@ struct sm501fb_info {
void __iomem *regs2d; /* 2d remapped registers */
void __iomem *fbmem; /* remapped framebuffer */
size_t fbmem_len; /* length of remapped region */
+ u8 *edid_data;
};
/* per-framebuffer private data */
@@ -1725,9 +1746,16 @@ static int sm501fb_init_fb(struct fb_info *fb,
fb->var.vmode = FB_VMODE_NONINTERLACED;
fb->var.bits_per_pixel = 16;
+ if (info->edid_data) {
+ /* Now build modedb from EDID */
+ fb_edid_to_monspecs(info->edid_data, &fb->monspecs);
+ fb_videomode_to_modelist(fb->monspecs.modedb,
+ fb->monspecs.modedb_len,
+ &fb->modelist);
+ }
+
if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) {
/* TODO read the mode from the current display */
-
} else {
if (pd->def_mode) {
dev_info(info->dev, "using supplied mode\n");
@@ -1737,12 +1765,34 @@ static int sm501fb_init_fb(struct fb_info *fb,
fb->var.xres_virtual = fb->var.xres;
fb->var.yres_virtual = fb->var.yres;
} else {
- ret = fb_find_mode(&fb->var, fb,
+ if (info->edid_data)
+ ret = fb_find_mode(&fb->var, fb, fb_mode,
+ fb->monspecs.modedb,
+ fb->monspecs.modedb_len,
+ &sm501_default_mode, default_bpp);
+ else
+ ret = fb_find_mode(&fb->var, fb,
NULL, NULL, 0, NULL, 8);
- if (ret == 0 || ret == 4) {
- dev_err(info->dev,
- "failed to get initial mode\n");
+ switch (ret) {
+ case 1:
+ dev_info(info->dev, "using mode specified in "
+ "@mode\n");
+ break;
+ case 2:
+ dev_info(info->dev, "using mode specified in "
+ "@mode with ignored refresh rate\n");
+ break;
+ case 3:
+ dev_info(info->dev, "using mode default "
+ "mode\n");
+ break;
+ case 4:
+ dev_info(info->dev, "using mode from list\n");
+ break;
+ default:
+ dev_info(info->dev, "ret = %d\n", ret);
+ dev_info(info->dev, "failed to find mode\n");
return -EINVAL;
}
}
@@ -2157,6 +2207,11 @@ static void __exit sm501fb_cleanup(void)
module_init(sm501fb_init);
module_exit(sm501fb_cleanup);
+module_param_named(mode, fb_mode, charp, 0);
+MODULE_PARM_DESC(mode,
+ "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
+module_param_named(bpp, default_bpp, ulong, 0);
+MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
MODULE_AUTHOR("Ben Dooks, Vincent Sanders");
MODULE_DESCRIPTION("SM501 Framebuffer driver");
MODULE_LICENSE("GPL v2");
--
1.7.4
^ permalink raw reply related
* [PATCH v6 0/6] powerpc, 52xx: add charon board support
From: Heiko Schocher @ 2011-03-22 8:27 UTC (permalink / raw)
To: linuxppc-dev
Cc: Ben Dooks, linux-fbdev, devicetree-discuss, Samuel Ortiz,
Vincent Sanders, linux-kernel, Randy Dunlap, Paul Mundt,
Heiko Schocher, Wolfgang Denk
In-Reply-To: <1291451028-22532-1-git-send-email-hs@denx.de>
cc: Wolfram Sang <w.sang@pengutronix.de>
cc: Grant Likely <grant.likely@secretlab.ca>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Wolfgang Denk <wd@denx.de>
cc: Paul Mundt <lethal@linux-sh.org>
changes since v5:
- repost complete patchseries, as Paul Mundt suggested
- rebased against current head
- add Acked-by from Samuel Ortiz (MFD parts)
http://www.spinics.net/lists/linux-fbdev/msg02550.html
http://linux.derkeiler.com/Mailing-Lists/Kernel/2011-01/msg11798.html
and Benjamin Herrenschmidt (DTS parts)
http://lists.ozlabs.org/pipermail/linuxppc-dev/2011-February/088279.html
- removed patch
"powerpc, mpc5200: update mpc5200_defconfig to fit for charon board."
therefore added
"powerpc, tqm5200: update tqm5200_defconfig to fit for charon board."
Paul: before adding this patchseries, this patch should get
an Acked-by from a powerpc maintainer.
checkpatch says:
total: 0 errors, 0 warnings, 233 lines checked
20110322/0001-powerpc-5200-add-support-for-charon-board.patch has no obvious style problems and is ready for submission.
total: 0 errors, 0 warnings, 841 lines checked
20110322/0002-video-sm501-add-I-O-functions-for-use-on-powerpc.patch has no obvious style problems and is ready for submission.
total: 0 errors, 0 warnings, 109 lines checked
20110322/0003-video-sm501-add-edid-and-commandline-support.patch has no obvious style problems and is ready for submission.
total: 0 errors, 0 warnings, 106 lines checked
20110322/0004-video-sm501-add-OF-binding-to-support-SM501.patch has no obvious style problems and is ready for submission.
total: 0 errors, 0 warnings, 22 lines checked
20110322/0005-powerpc-video-add-SM501-support-for-charon-board.patch has no obvious style problems and is ready for submission.
total: 0 errors, 0 warnings, 82 lines checked
20110322/0006-powerpc-tqm5200-update-tqm5200_defconfig-to-fit-for-.patch has no obvious style problems and is ready for submission.
Heiko Schocher (6):
powerpc, 5200: add support for charon board
video, sm501: add I/O functions for use on powerpc
video, sm501: add edid and commandline support
video, sm501: add OF binding to support SM501
powerpc, video: add SM501 support for charon board.
powerpc, tqm5200: update tqm5200_defconfig to fit for charon board.
Documentation/fb/sm501.txt | 10 +
Documentation/powerpc/dts-bindings/sm501.txt | 34 ++++
arch/powerpc/boot/dts/charon.dts | 236 ++++++++++++++++++++++
arch/powerpc/configs/52xx/tqm5200_defconfig | 20 ++-
arch/powerpc/platforms/52xx/mpc5200_simple.c | 1 +
drivers/mfd/sm501.c | 133 +++++++------
drivers/video/sm501fb.c | 272 +++++++++++++++++---------
include/linux/sm501.h | 8 +
8 files changed, 555 insertions(+), 159 deletions(-)
create mode 100644 Documentation/fb/sm501.txt
create mode 100644 Documentation/powerpc/dts-bindings/sm501.txt
create mode 100644 arch/powerpc/boot/dts/charon.dts
--
1.7.4
^ permalink raw reply
* [PATCH v6 6/6] powerpc, tqm5200: update tqm5200_defconfig to fit for charon board.
From: Heiko Schocher @ 2011-03-22 8:27 UTC (permalink / raw)
To: linuxppc-dev
Cc: Ben Dooks, linux-fbdev, devicetree-discuss, Samuel Ortiz,
Vincent Sanders, linux-kernel, Randy Dunlap, Paul Mundt,
Heiko Schocher, Wolfgang Denk
In-Reply-To: <1300782452-528-1-git-send-email-hs@denx.de>
added:
CONFIG_MTD_OF_PARTS
CONFIG_MTD_PLATRAM
CONFIG_FIXED_PHY
CONFIG_SENSORS_LM80
CONFIG_MFD_SM501
CONFIG_FB
CONFIG_FB_FOREIGN_ENDIAN
CONFIG_FB_SM501
CONFIG_FRAMEBUFFER_CONSOLE
CONFIG_RTC_DRV_DS1374
Signed-off-by: Heiko Schocher <hs@denx.de>
cc: Wolfram Sang <w.sang@pengutronix.de>
cc: Grant Likely <grant.likely@secretlab.ca>
cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Wolfgang Denk <wd@denx.de>
cc: Paul Mundt <lethal@linux-sh.org>
---
- changes since v1:
added Grant Likely to cc
- changes for v6:
- new in this version, therefore patch
"powerpc, mpc5200: update mpc5200_defconfig to fit for charon board."
removed.
As this board is tqm5200 based, added necessary changes
to the tqm5200_defconfig. In previous patchserie I added
the changes to mpc5200_defconfig, as Wolfram Sang mentioned,
but as tqm5200_defconfig is in mainline, and the board is
tqm5200 based, I think, thats the appropriate place, as
new defconfigs are not accepted. Paul, before applying
this patch series, this patch should get an Acked by
from a powerpc maintainer...
- repost the complete patchserie as Paul Mundt suggested
arch/powerpc/configs/52xx/tqm5200_defconfig | 20 ++++++++++++--------
1 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig
index 959cd2c..716a37b 100644
--- a/arch/powerpc/configs/52xx/tqm5200_defconfig
+++ b/arch/powerpc/configs/52xx/tqm5200_defconfig
@@ -1,9 +1,10 @@
CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
+CONFIG_SPARSE_IRQ=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
+CONFIG_EMBEDDED=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_KALLSYMS is not set
# CONFIG_EPOLL is not set
@@ -17,7 +18,6 @@ CONFIG_PPC_MPC5200_SIMPLE=y
CONFIG_PPC_MPC5200_BUGFIX=y
# CONFIG_PPC_PMAC is not set
CONFIG_PPC_BESTCOMM=y
-CONFIG_SPARSE_IRQ=y
CONFIG_PM=y
# CONFIG_PCI is not set
CONFIG_NET=y
@@ -38,17 +38,18 @@ CONFIG_MTD=y
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_ROM=y
CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_PLATRAM=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=32768
-# CONFIG_MISC_DEVICES is not set
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_ATA=y
@@ -56,13 +57,11 @@ CONFIG_PATA_MPC52xx=y
CONFIG_PATA_PLATFORM=y
CONFIG_NETDEVICES=y
CONFIG_LXT_PHY=y
+CONFIG_FIXED_PHY=y
CONFIG_NET_ETHERNET=y
CONFIG_FEC_MPC52xx=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
CONFIG_SERIAL_MPC52xx=y
CONFIG_SERIAL_MPC52xx_CONSOLE=y
CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
@@ -70,7 +69,13 @@ CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MPC=y
+CONFIG_SENSORS_LM80=y
CONFIG_WATCHDOG=y
+CONFIG_MFD_SM501=y
+CONFIG_FB=y
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_SM501=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_USB=y
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
@@ -80,10 +85,10 @@ CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_STORAGE=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1374=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_INOTIFY=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_PROC_KCORE=y
@@ -102,7 +107,6 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
--
1.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox