aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2008-03-27 14:51:39 -0400
committerNicolas Pitre <nico@marvell.com>2008-03-27 14:51:39 -0400
commit15a32632d94011911497052a96cdbf3b905b325d (patch)
tree75d5d0c378157f19ccd12a1615a83c6aa2226689
parent92aecfa95523384923b52c8ddaf948fc02a53e82 (diff)
sata_mv: mbus decode window support
Make it possible to pass mbus_dram_target_info to the sata_mv driver via the platform data, make the sata_mv driver program the window registers based on this data if it is passed in, and make the Orion platform setup code use this method instead of programming the SATA mbus window registers by hand. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Reviewed-by: Tzachi Perelstein <tzachi@marvell.com> Acked-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Nicolas Pitre <nico@marvell.com>
-rw-r--r--arch/arm/mach-orion/addr-map.c39
-rw-r--r--arch/arm/mach-orion/common.c4
-rw-r--r--arch/arm/mach-orion/common.h1
-rw-r--r--drivers/ata/sata_mv.c31
-rw-r--r--include/linux/ata_platform.h3
5 files changed, 36 insertions, 42 deletions
diff --git a/arch/arm/mach-orion/addr-map.c b/arch/arm/mach-orion/addr-map.c
index 40bcb986ab96..3de5de9ac656 100644
--- a/arch/arm/mach-orion/addr-map.c
+++ b/arch/arm/mach-orion/addr-map.c
@@ -103,13 +103,6 @@
103#define ETH_MAX_WIN 6 103#define ETH_MAX_WIN 6
104#define ETH_MAX_REMAP_WIN 4 104#define ETH_MAX_REMAP_WIN 4
105 105
106/*
107 * SATA Address Decode Windows registers
108 */
109#define SATA_WIN_CTRL(win) ORION_SATA_REG(0x30 + ((win) * 0x10))
110#define SATA_WIN_BASE(win) ORION_SATA_REG(0x34 + ((win) * 0x10))
111#define SATA_MAX_WIN 4
112
113 106
114struct mbus_dram_target_info orion_mbus_dram_info; 107struct mbus_dram_target_info orion_mbus_dram_info;
115 108
@@ -288,35 +281,3 @@ void __init orion_setup_eth_wins(void)
288 } 281 }
289 } 282 }
290} 283}
291
292void __init orion_setup_sata_wins(void)
293{
294 int i;
295
296 /*
297 * First, disable and clear windows
298 */
299 for (i = 0; i < SATA_MAX_WIN; i++) {
300 orion_write(SATA_WIN_BASE(i), 0);
301 orion_write(SATA_WIN_CTRL(i), 0);
302 }
303
304 /*
305 * Setup windows for DDR banks.
306 */
307 for (i = 0; i < DDR_MAX_CS; i++) {
308 u32 base, size;
309 size = orion_read(DDR_SIZE_CS(i));
310 base = orion_read(DDR_BASE_CS(i));
311 if (size & DDR_BANK_EN) {
312 base = DDR_REG_TO_BASE(base);
313 size = DDR_REG_TO_SIZE(size);
314 orion_write(SATA_WIN_CTRL(i),
315 ((size-1) & 0xffff0000) |
316 (ATTR_DDR_CS(i) << 8) |
317 (TARGET_DDR << 4) | WIN_EN);
318 orion_write(SATA_WIN_BASE(i),
319 base & 0xffff0000);
320 }
321 }
322}
diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c
index d33c01dfc3f2..a32fe8e108bc 100644
--- a/arch/arm/mach-orion/common.c
+++ b/arch/arm/mach-orion/common.c
@@ -17,6 +17,7 @@
17#include <linux/mbus.h> 17#include <linux/mbus.h>
18#include <linux/mv643xx_eth.h> 18#include <linux/mv643xx_eth.h>
19#include <linux/mv643xx_i2c.h> 19#include <linux/mv643xx_i2c.h>
20#include <linux/ata_platform.h>
20#include <asm/page.h> 21#include <asm/page.h>
21#include <asm/setup.h> 22#include <asm/setup.h>
22#include <asm/timex.h> 23#include <asm/timex.h>
@@ -289,6 +290,7 @@ static struct platform_device orion_sata = {
289 290
290void __init orion_sata_init(struct mv_sata_platform_data *sata_data) 291void __init orion_sata_init(struct mv_sata_platform_data *sata_data)
291{ 292{
293 sata_data->dram = &orion_mbus_dram_info;
292 orion_sata.dev.platform_data = sata_data; 294 orion_sata.dev.platform_data = sata_data;
293 platform_device_register(&orion_sata); 295 platform_device_register(&orion_sata);
294} 296}
@@ -342,8 +344,6 @@ void __init orion_init(void)
342 */ 344 */
343 orion_setup_cpu_wins(); 345 orion_setup_cpu_wins();
344 orion_setup_eth_wins(); 346 orion_setup_eth_wins();
345 if (dev == MV88F5182_DEV_ID)
346 orion_setup_sata_wins();
347 347
348 /* 348 /*
349 * REgister devices 349 * REgister devices
diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h
index c100355754f3..b676be0a4a86 100644
--- a/arch/arm/mach-orion/common.h
+++ b/arch/arm/mach-orion/common.h
@@ -33,7 +33,6 @@ extern struct mbus_dram_target_info orion_mbus_dram_info;
33void orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap); 33void orion_setup_cpu_win(enum orion_target target, u32 base, u32 size, int remap);
34void orion_setup_cpu_wins(void); 34void orion_setup_cpu_wins(void);
35void orion_setup_eth_wins(void); 35void orion_setup_eth_wins(void);
36void orion_setup_sata_wins(void);
37 36
38/* 37/*
39 * Shared code used internally by other Orion core functions. 38 * Shared code used internally by other Orion core functions.
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 6ebebde8454a..83584b6e1ba5 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -74,6 +74,7 @@
74#include <linux/device.h> 74#include <linux/device.h>
75#include <linux/platform_device.h> 75#include <linux/platform_device.h>
76#include <linux/ata_platform.h> 76#include <linux/ata_platform.h>
77#include <linux/mbus.h>
77#include <scsi/scsi_host.h> 78#include <scsi/scsi_host.h>
78#include <scsi/scsi_cmnd.h> 79#include <scsi/scsi_cmnd.h>
79#include <scsi/scsi_device.h> 80#include <scsi/scsi_device.h>
@@ -352,6 +353,9 @@ enum {
352#define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) 353#define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
353#define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC)) 354#define HAS_PCI(host) (!((host)->ports[0]->flags & MV_FLAG_SOC))
354 355
356#define WINDOW_CTRL(i) (0x20030 + ((i) << 4))
357#define WINDOW_BASE(i) (0x20034 + ((i) << 4))
358
355enum { 359enum {
356 /* DMA boundary 0xffff is required by the s/g splitting 360 /* DMA boundary 0xffff is required by the s/g splitting
357 * we need on /length/ in mv_fill-sg(). 361 * we need on /length/ in mv_fill-sg().
@@ -2897,6 +2901,27 @@ static int mv_create_dma_pools(struct mv_host_priv *hpriv, struct device *dev)
2897 return 0; 2901 return 0;
2898} 2902}
2899 2903
2904static void mv_conf_mbus_windows(struct mv_host_priv *hpriv,
2905 struct mbus_dram_target_info *dram)
2906{
2907 int i;
2908
2909 for (i = 0; i < 4; i++) {
2910 writel(0, hpriv->base + WINDOW_CTRL(i));
2911 writel(0, hpriv->base + WINDOW_BASE(i));
2912 }
2913
2914 for (i = 0; i < dram->num_cs; i++) {
2915 struct mbus_dram_window *cs = dram->cs + i;
2916
2917 writel(((cs->size - 1) & 0xffff0000) |
2918 (cs->mbus_attr << 8) |
2919 (dram->mbus_dram_target_id << 4) | 1,
2920 hpriv->base + WINDOW_CTRL(i));
2921 writel(cs->base, hpriv->base + WINDOW_BASE(i));
2922 }
2923}
2924
2900/** 2925/**
2901 * mv_platform_probe - handle a positive probe of an soc Marvell 2926 * mv_platform_probe - handle a positive probe of an soc Marvell
2902 * host 2927 * host
@@ -2951,6 +2976,12 @@ static int mv_platform_probe(struct platform_device *pdev)
2951 res->end - res->start + 1); 2976 res->end - res->start + 1);
2952 hpriv->base -= MV_SATAHC0_REG_BASE; 2977 hpriv->base -= MV_SATAHC0_REG_BASE;
2953 2978
2979 /*
2980 * (Re-)program MBUS remapping windows if we are asked to.
2981 */
2982 if (mv_platform_data->dram != NULL)
2983 mv_conf_mbus_windows(hpriv, mv_platform_data->dram);
2984
2954 rc = mv_create_dma_pools(hpriv, &pdev->dev); 2985 rc = mv_create_dma_pools(hpriv, &pdev->dev);
2955 if (rc) 2986 if (rc)
2956 return rc; 2987 return rc;
diff --git a/include/linux/ata_platform.h b/include/linux/ata_platform.h
index b856a2a590d9..9a26c83a2c9e 100644
--- a/include/linux/ata_platform.h
+++ b/include/linux/ata_platform.h
@@ -27,7 +27,10 @@ extern int __devexit __pata_platform_remove(struct device *dev);
27/* 27/*
28 * Marvell SATA private data 28 * Marvell SATA private data
29 */ 29 */
30struct mbus_dram_target_info;
31
30struct mv_sata_platform_data { 32struct mv_sata_platform_data {
33 struct mbus_dram_target_info *dram;
31 int n_ports; /* number of sata ports */ 34 int n_ports; /* number of sata ports */
32}; 35};
33 36