From 9b36f748162e3d09b16df5b7c670d183292ecdc1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Apr 2017 11:34:52 -0600 Subject: dm: led: Add a missing blank line in the Kconfig file There should be a blank line between each option. Add one before LED_GPIO. Signed-off-by: Simon Glass Reviewed-by: Ziping Chen --- drivers/led/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig index 609b1fa3fe9..0ef45bc06a2 100644 --- a/drivers/led/Kconfig +++ b/drivers/led/Kconfig @@ -17,6 +17,7 @@ config SPL_LED If this is acceptable and you have a need to use LEDs in SPL, enable this option. You will need to enable device tree in SPL for this to work. + config LED_GPIO bool "LED support for GPIO-connected LEDs" depends on LED && DM_GPIO -- cgit v1.3.1 From 56e19871dc2a05aa5508ea51af35df59bbdb6cf5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Apr 2017 11:34:53 -0600 Subject: dm: led: Rename struct led_uclass_plat These structures are normally named with 'uc' instead of 'uclass'. Change this one for consistency. Signed-off-by: Simon Glass Reviewed-by: Ziping Chen --- drivers/led/led-uclass.c | 4 ++-- drivers/led/led_gpio.c | 4 ++-- include/led.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c index 784ac870e27..ca4f98c0b35 100644 --- a/drivers/led/led-uclass.c +++ b/drivers/led/led-uclass.c @@ -22,7 +22,7 @@ int led_get_by_label(const char *label, struct udevice **devp) if (ret) return ret; uclass_foreach_dev(dev, uc) { - struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev); + struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev); /* Ignore the top-level LED node */ if (uc_plat->label && !strcmp(label, uc_plat->label)) @@ -45,5 +45,5 @@ int led_set_on(struct udevice *dev, int on) UCLASS_DRIVER(led) = { .id = UCLASS_LED, .name = "led", - .per_device_platdata_auto_alloc_size = sizeof(struct led_uclass_plat), + .per_device_platdata_auto_alloc_size = sizeof(struct led_uc_plat), }; diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c index 5b119903f55..97b5da35cd4 100644 --- a/drivers/led/led_gpio.c +++ b/drivers/led/led_gpio.c @@ -30,7 +30,7 @@ static int gpio_led_set_on(struct udevice *dev, int on) static int led_gpio_probe(struct udevice *dev) { - struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev); + struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev); struct led_gpio_priv *priv = dev_get_priv(dev); /* Ignore the top-level LED node */ @@ -65,7 +65,7 @@ static int led_gpio_bind(struct udevice *parent) for (node = fdt_first_subnode(blob, dev_of_offset(parent)); node > 0; node = fdt_next_subnode(blob, node)) { - struct led_uclass_plat *uc_plat; + struct led_uc_plat *uc_plat; const char *label; label = fdt_getprop(blob, node, "label", NULL); diff --git a/include/led.h b/include/led.h index b929d0ca3c7..a856b3d9ff7 100644 --- a/include/led.h +++ b/include/led.h @@ -9,11 +9,11 @@ #define __LED_H /** - * struct led_uclass_plat - Platform data the uclass stores about each device + * struct led_uc_plat - Platform data the uclass stores about each device * * @label: LED label */ -struct led_uclass_plat { +struct led_uc_plat { const char *label; }; -- cgit v1.3.1 From ddae9fcddc48d1e624c941148d0df5a4fc7d7d5c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Apr 2017 11:34:54 -0600 Subject: dm: led: Adjust the LED uclass At present this is very simple, supporting only on and off. We want to also support toggling and blinking. As a first step, change the name of the main method and use an enum to indicate the state. Signed-off-by: Simon Glass Reviewed-by: Ziping Chen --- drivers/led/led-uclass.c | 6 +++--- drivers/led/led_gpio.c | 6 +++--- include/led.h | 19 +++++++++++++------ test/dm/led.c | 5 +++-- 4 files changed, 22 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c index ca4f98c0b35..b30346913b9 100644 --- a/drivers/led/led-uclass.c +++ b/drivers/led/led-uclass.c @@ -32,14 +32,14 @@ int led_get_by_label(const char *label, struct udevice **devp) return -ENODEV; } -int led_set_on(struct udevice *dev, int on) +int led_set_state(struct udevice *dev, enum led_state_t state) { struct led_ops *ops = led_get_ops(dev); - if (!ops->set_on) + if (!ops->set_state) return -ENOSYS; - return ops->set_on(dev, on); + return ops->set_state(dev, state); } UCLASS_DRIVER(led) = { diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c index 97b5da35cd4..af8133d3c70 100644 --- a/drivers/led/led_gpio.c +++ b/drivers/led/led_gpio.c @@ -18,14 +18,14 @@ struct led_gpio_priv { struct gpio_desc gpio; }; -static int gpio_led_set_on(struct udevice *dev, int on) +static int gpio_led_set_state(struct udevice *dev, enum led_state_t state) { struct led_gpio_priv *priv = dev_get_priv(dev); if (!dm_gpio_is_valid(&priv->gpio)) return -EREMOTEIO; - return dm_gpio_set_value(&priv->gpio, on); + return dm_gpio_set_value(&priv->gpio, state); } static int led_gpio_probe(struct udevice *dev) @@ -87,7 +87,7 @@ static int led_gpio_bind(struct udevice *parent) } static const struct led_ops gpio_led_ops = { - .set_on = gpio_led_set_on, + .set_state = gpio_led_set_state, }; static const struct udevice_id led_gpio_ids[] = { diff --git a/include/led.h b/include/led.h index a856b3d9ff7..8af87ea8ea8 100644 --- a/include/led.h +++ b/include/led.h @@ -17,15 +17,22 @@ struct led_uc_plat { const char *label; }; +enum led_state_t { + LEDST_OFF = 0, + LEDST_ON = 1, + + LEDST_COUNT, +}; + struct led_ops { /** - * set_on() - set the state of an LED + * set_state() - set the state of an LED * * @dev: LED device to change - * @on: 1 to turn the LED on, 0 to turn it off + * @state: LED state to set * @return 0 if OK, -ve on error */ - int (*set_on)(struct udevice *dev, int on); + int (*set_state)(struct udevice *dev, enum led_state_t state); }; #define led_get_ops(dev) ((struct led_ops *)(dev)->driver->ops) @@ -40,12 +47,12 @@ struct led_ops { int led_get_by_label(const char *label, struct udevice **devp); /** - * led_set_on() - set the state of an LED + * led_set_state() - set the state of an LED * * @dev: LED device to change - * @on: 1 to turn the LED on, 0 to turn it off + * @state: LED state to set * @return 0 if OK, -ve on error */ -int led_set_on(struct udevice *dev, int on); +int led_set_state(struct udevice *dev, enum led_state_t state); #endif diff --git a/test/dm/led.c b/test/dm/led.c index 8ee075cf1ca..ebb9b465848 100644 --- a/test/dm/led.c +++ b/test/dm/led.c @@ -41,9 +41,10 @@ static int dm_test_led_gpio(struct unit_test_state *uts) ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev)); ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio)); ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); - led_set_on(dev, 1); + ut_assertok(led_set_state(dev, LEDST_ON)); ut_asserteq(1, sandbox_gpio_get_value(gpio, offset)); - led_set_on(dev, 0); + + ut_assertok(led_set_state(dev, LEDST_OFF)); ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); return 0; -- cgit v1.3.1 From 8f4b612333ee0381eedf767c1c005a830886df27 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Apr 2017 11:34:55 -0600 Subject: dm: led: Add support for getting the state of an LED It is useful to be able to read the LED as well as write it. Add this to the uclass and update the GPIO driver. Signed-off-by: Simon Glass Reviewed-by: Ziping Chen --- drivers/led/led-uclass.c | 10 ++++++++++ drivers/led/led_gpio.c | 22 ++++++++++++++++++++++ include/led.h | 16 ++++++++++++++++ test/dm/led.c | 2 ++ 4 files changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c index b30346913b9..ea5fbabadf3 100644 --- a/drivers/led/led-uclass.c +++ b/drivers/led/led-uclass.c @@ -42,6 +42,16 @@ int led_set_state(struct udevice *dev, enum led_state_t state) return ops->set_state(dev, state); } +enum led_state_t led_get_state(struct udevice *dev) +{ + struct led_ops *ops = led_get_ops(dev); + + if (!ops->get_state) + return -ENOSYS; + + return ops->get_state(dev); +} + UCLASS_DRIVER(led) = { .id = UCLASS_LED, .name = "led", diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c index af8133d3c70..789d15600fd 100644 --- a/drivers/led/led_gpio.c +++ b/drivers/led/led_gpio.c @@ -24,10 +24,31 @@ static int gpio_led_set_state(struct udevice *dev, enum led_state_t state) if (!dm_gpio_is_valid(&priv->gpio)) return -EREMOTEIO; + switch (state) { + case LEDST_OFF: + case LEDST_ON: + break; + default: + return -ENOSYS; + } return dm_gpio_set_value(&priv->gpio, state); } +static enum led_state_t gpio_led_get_state(struct udevice *dev) +{ + struct led_gpio_priv *priv = dev_get_priv(dev); + int ret; + + if (!dm_gpio_is_valid(&priv->gpio)) + return -EREMOTEIO; + ret = dm_gpio_get_value(&priv->gpio); + if (ret < 0) + return ret; + + return ret ? LEDST_ON : LEDST_OFF; +} + static int led_gpio_probe(struct udevice *dev) { struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev); @@ -88,6 +109,7 @@ static int led_gpio_bind(struct udevice *parent) static const struct led_ops gpio_led_ops = { .set_state = gpio_led_set_state, + .get_state = gpio_led_get_state, }; static const struct udevice_id led_gpio_ids[] = { diff --git a/include/led.h b/include/led.h index 8af87ea8ea8..bbab4d14c98 100644 --- a/include/led.h +++ b/include/led.h @@ -33,6 +33,14 @@ struct led_ops { * @return 0 if OK, -ve on error */ int (*set_state)(struct udevice *dev, enum led_state_t state); + + /** + * led_get_state() - get the state of an LED + * + * @dev: LED device to change + * @return LED state led_state_t, or -ve on error + */ + enum led_state_t (*get_state)(struct udevice *dev); }; #define led_get_ops(dev) ((struct led_ops *)(dev)->driver->ops) @@ -55,4 +63,12 @@ int led_get_by_label(const char *label, struct udevice **devp); */ int led_set_state(struct udevice *dev, enum led_state_t state); +/** + * led_get_state() - get the state of an LED + * + * @dev: LED device to change + * @return LED state led_state_t, or -ve on error + */ +enum led_state_t led_get_state(struct udevice *dev); + #endif diff --git a/test/dm/led.c b/test/dm/led.c index ebb9b465848..68aa39bd4d0 100644 --- a/test/dm/led.c +++ b/test/dm/led.c @@ -43,9 +43,11 @@ static int dm_test_led_gpio(struct unit_test_state *uts) ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); ut_assertok(led_set_state(dev, LEDST_ON)); ut_asserteq(1, sandbox_gpio_get_value(gpio, offset)); + ut_asserteq(LEDST_ON, led_get_state(dev)); ut_assertok(led_set_state(dev, LEDST_OFF)); ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); + ut_asserteq(LEDST_OFF, led_get_state(dev)); return 0; } -- cgit v1.3.1 From 9413ad4f0def2e06a5042106a6e1650a1aa03a5a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Apr 2017 11:34:56 -0600 Subject: dm: led: Support toggling LEDs Add support for toggling an LED into the uclass interface. This can be efficiently implemented by the driver. Signed-off-by: Simon Glass Reviewed-by: Ziping Chen --- drivers/led/led_gpio.c | 7 +++++++ include/led.h | 1 + test/dm/led.c | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+) (limited to 'drivers') diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c index 789d15600fd..4106ecb6799 100644 --- a/drivers/led/led_gpio.c +++ b/drivers/led/led_gpio.c @@ -21,6 +21,7 @@ struct led_gpio_priv { static int gpio_led_set_state(struct udevice *dev, enum led_state_t state) { struct led_gpio_priv *priv = dev_get_priv(dev); + int ret; if (!dm_gpio_is_valid(&priv->gpio)) return -EREMOTEIO; @@ -28,6 +29,12 @@ static int gpio_led_set_state(struct udevice *dev, enum led_state_t state) case LEDST_OFF: case LEDST_ON: break; + case LEDST_TOGGLE: + ret = dm_gpio_get_value(&priv->gpio); + if (ret < 0) + return ret; + state = !ret; + break; default: return -ENOSYS; } diff --git a/include/led.h b/include/led.h index bbab4d14c98..8c107e28e78 100644 --- a/include/led.h +++ b/include/led.h @@ -20,6 +20,7 @@ struct led_uc_plat { enum led_state_t { LEDST_OFF = 0, LEDST_ON = 1, + LEDST_TOGGLE, LEDST_COUNT, }; diff --git a/test/dm/led.c b/test/dm/led.c index 68aa39bd4d0..2cc24127e2a 100644 --- a/test/dm/led.c +++ b/test/dm/led.c @@ -53,6 +53,31 @@ static int dm_test_led_gpio(struct unit_test_state *uts) } DM_TEST(dm_test_led_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +/* Test that we can toggle LEDs */ +static int dm_test_led_toggle(struct unit_test_state *uts) +{ + const int offset = 1; + struct udevice *dev, *gpio; + + /* + * Check that we can manipulate an LED. LED 1 is connected to GPIO + * bank gpio_a, offset 1. + */ + ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev)); + ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio)); + ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); + ut_assertok(led_set_state(dev, LEDST_TOGGLE)); + ut_asserteq(1, sandbox_gpio_get_value(gpio, offset)); + ut_asserteq(LEDST_ON, led_get_state(dev)); + + ut_assertok(led_set_state(dev, LEDST_TOGGLE)); + ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); + ut_asserteq(LEDST_OFF, led_get_state(dev)); + + return 0; +} +DM_TEST(dm_test_led_toggle, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + /* Test obtaining an LED by label */ static int dm_test_led_label(struct unit_test_state *uts) { -- cgit v1.3.1 From 53378dac8dc33e3fd5f07d60bd7a5f8258ac7a20 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 10 Apr 2017 11:34:57 -0600 Subject: dm: led: Add support for blinking LEDs Allow LEDs to be blinked if the driver supports it. Enable this for sandbox so that the tests run. Signed-off-by: Simon Glass Reviewed-by: Ziping Chen --- configs/sandbox_defconfig | 1 + configs/sandbox_noblk_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + drivers/led/Kconfig | 9 +++++++++ drivers/led/led-uclass.c | 12 ++++++++++++ include/led.h | 35 +++++++++++++++++++++++++++++++++++ test/dm/led.c | 24 ++++++++++++++++++++++++ 7 files changed, 83 insertions(+) (limited to 'drivers') diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 7f3f5ac8095..9814ea3b819 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -83,6 +83,7 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=y CONFIG_CROS_EC_KEYB=y CONFIG_I8042_KEYB=y CONFIG_LED=y +CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y CONFIG_DM_MAILBOX=y CONFIG_SANDBOX_MBOX=y diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig index 3f8e70d5237..bba744332c2 100644 --- a/configs/sandbox_noblk_defconfig +++ b/configs/sandbox_noblk_defconfig @@ -92,6 +92,7 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=y CONFIG_CROS_EC_KEYB=y CONFIG_I8042_KEYB=y CONFIG_LED=y +CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y CONFIG_CROS_EC=y CONFIG_CROS_EC_I2C=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index ade67143b1c..6fe21254fd8 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -94,6 +94,7 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=y CONFIG_CROS_EC_KEYB=y CONFIG_I8042_KEYB=y CONFIG_LED=y +CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y CONFIG_DM_MAILBOX=y CONFIG_SANDBOX_MBOX=y diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig index 0ef45bc06a2..309372ab564 100644 --- a/drivers/led/Kconfig +++ b/drivers/led/Kconfig @@ -9,6 +9,15 @@ config LED can provide access to board-specific LEDs. Use of the device tree for configuration is encouraged. +config LED_BLINK + bool "Support LED blinking" + depends on LED + help + Some drivers can support automatic blinking of LEDs with a given + period, without needing timers or extra code to handle the timing. + This option enables support for this which adds slightly to the + code size. + config SPL_LED bool "Enable LED support in SPL" depends on SPL && SPL_DM diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c index ea5fbabadf3..78ab76050d6 100644 --- a/drivers/led/led-uclass.c +++ b/drivers/led/led-uclass.c @@ -52,6 +52,18 @@ enum led_state_t led_get_state(struct udevice *dev) return ops->get_state(dev); } +#ifdef CONFIG_LED_BLINK +int led_set_period(struct udevice *dev, int period_ms) +{ + struct led_ops *ops = led_get_ops(dev); + + if (!ops->set_period) + return -ENOSYS; + + return ops->set_period(dev, period_ms); +} +#endif + UCLASS_DRIVER(led) = { .id = UCLASS_LED, .name = "led", diff --git a/include/led.h b/include/led.h index 8c107e28e78..c67af225912 100644 --- a/include/led.h +++ b/include/led.h @@ -17,10 +17,22 @@ struct led_uc_plat { const char *label; }; +/** + * struct led_uc_priv - Private data the uclass stores about each device + * + * @period_ms: Flash period in milliseconds + */ +struct led_uc_priv { + int period_ms; +}; + enum led_state_t { LEDST_OFF = 0, LEDST_ON = 1, LEDST_TOGGLE, +#ifdef CONFIG_LED_BLINK + LEDST_BLINK, +#endif LEDST_COUNT, }; @@ -42,6 +54,20 @@ struct led_ops { * @return LED state led_state_t, or -ve on error */ enum led_state_t (*get_state)(struct udevice *dev); + +#ifdef CONFIG_LED_BLINK + /** + * led_set_period() - set the blink period of an LED + * + * Thie records the period if supported, or returns -ENOSYS if not. + * To start the LED blinking, use set_state(). + * + * @dev: LED device to change + * @period_ms: LED blink period in milliseconds + * @return 0 if OK, -ve on error + */ + int (*set_period)(struct udevice *dev, int period_ms); +#endif }; #define led_get_ops(dev) ((struct led_ops *)(dev)->driver->ops) @@ -72,4 +98,13 @@ int led_set_state(struct udevice *dev, enum led_state_t state); */ enum led_state_t led_get_state(struct udevice *dev); +/** + * led_set_period() - set the blink period of an LED + * + * @dev: LED device to change + * @period_ms: LED blink period in milliseconds + * @return 0 if OK, -ve on error + */ +int led_set_period(struct udevice *dev, int period_ms); + #endif diff --git a/test/dm/led.c b/test/dm/led.c index 2cc24127e2a..fde700be386 100644 --- a/test/dm/led.c +++ b/test/dm/led.c @@ -98,3 +98,27 @@ static int dm_test_led_label(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_led_label, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test LED blinking */ +#ifdef CONFIG_LED_BLINK +static int dm_test_led_blink(struct unit_test_state *uts) +{ + const int offset = 1; + struct udevice *dev, *gpio; + + /* + * Check that we get an error when trying to blink an LED, since it is + * not supported by the GPIO LED driver. + */ + ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev)); + ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio)); + ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); + ut_asserteq(-ENOSYS, led_set_state(dev, LEDST_BLINK)); + ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); + ut_asserteq(LEDST_OFF, led_get_state(dev)); + ut_asserteq(-ENOSYS, led_set_period(dev, 100)); + + return 0; +} +DM_TEST(dm_test_led_blink, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +#endif -- cgit v1.3.1 From 4e5439ac25486e34568d96f99fefb464a857855c Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Fri, 7 Apr 2017 12:38:52 +0200 Subject: rockchip: sysreset: rk3188: Make sure remap is off on warm-resets The warm-reset of rk3188 socs keeps the remap setting as it was, so if it was enabled, the cpu would start from address 0x0 of the sram instead of address 0x0 of the bootrom, thus making the reset hang. Therefore make sure the remap is disabled before attempting a warm reset. Cold reset is not affected by this at all. Signed-off-by: Heiko Stuebner Acked-by: Simon Glass --- drivers/sysreset/sysreset_rk3188.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/sysreset/sysreset_rk3188.c b/drivers/sysreset/sysreset_rk3188.c index 36ae47600a5..053a6344f53 100644 --- a/drivers/sysreset/sysreset_rk3188.c +++ b/drivers/sysreset/sysreset_rk3188.c @@ -7,21 +7,36 @@ #include #include #include +#include #include #include #include #include +#include #include #include int rk3188_sysreset_request(struct udevice *dev, enum sysreset_t type) { struct rk3188_cru *cru = rockchip_get_cru(); + struct rk3188_grf *grf; if (IS_ERR(cru)) return PTR_ERR(cru); switch (type) { case SYSRESET_WARM: + grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + if (IS_ERR(grf)) + return -EPROTONOSUPPORT; + + /* + * warm-reset keeps the remap value, + * so make sure it's disabled. + */ + rk_clrsetreg(&grf->soc_con0, + NOC_REMAP_MASK << NOC_REMAP_SHIFT, + 0 << NOC_REMAP_SHIFT); + rk_clrreg(&cru->cru_mode_con, 0xffff); writel(0xeca8, &cru->cru_glb_srst_snd_value); break; -- cgit v1.3.1 From b644354a7c255defe0086c15ccb6b298f27a8bcf Mon Sep 17 00:00:00 2001 From: "eric.gao@rock-chips.com" Date: Mon, 10 Apr 2017 10:17:03 +0800 Subject: rockchip: i2c: Enable i2c for rk3399 To enable mipi display, we need to enable pmic rk808 first for lcd3v3 power,which use i2c0 to communicate with soc. So enable i2c0. Signed-off-by: Eric Gao Acked-by: Simon Glass --- arch/arm/dts/rk3399.dtsi | 16 ++++++++++++++++ configs/evb-rk3399_defconfig | 1 + drivers/i2c/rk_i2c.c | 1 + 3 files changed, 18 insertions(+) (limited to 'drivers') diff --git a/arch/arm/dts/rk3399.dtsi b/arch/arm/dts/rk3399.dtsi index dbe55f2b32a..d94d7802cb4 100644 --- a/arch/arm/dts/rk3399.dtsi +++ b/arch/arm/dts/rk3399.dtsi @@ -26,6 +26,7 @@ serial4 = &uart4; mmc0 = &sdhci; mmc1 = &sdmmc; + i2c0 = &i2c0; }; cpus { @@ -668,6 +669,21 @@ status = "disabled"; }; + i2c0: i2c@ff3c0000 { + compatible = "rockchip,rk3399-i2c"; + reg = <0x0 0xff3c0000 0x0 0x1000>; + assigned-clocks = <&pmucru SCLK_I2C0_PMU>; + assigned-clock-rates = <200000000>; + clocks = <&pmucru SCLK_I2C0_PMU>, <&pmucru PCLK_I2C0_PMU>; + clock-names = "i2c", "pclk"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + pinctrl: pinctrl { u-boot,dm-pre-reloc; compatible = "rockchip,rk3399-pinctrl"; diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig index 50b0d749abb..c644084cdfc 100644 --- a/configs/evb-rk3399_defconfig +++ b/configs/evb-rk3399_defconfig @@ -60,3 +60,4 @@ CONFIG_USB_EHCI_GENERIC=y CONFIG_USB_STORAGE=y CONFIG_USE_TINY_PRINTF=y CONFIG_ERRNO_STR=y +CONFIG_SYS_I2C_ROCKCHIP=y diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c index af925cecdbb..76f41f7e857 100644 --- a/drivers/i2c/rk_i2c.c +++ b/drivers/i2c/rk_i2c.c @@ -383,6 +383,7 @@ static const struct udevice_id rockchip_i2c_ids[] = { { .compatible = "rockchip,rk3066-i2c" }, { .compatible = "rockchip,rk3188-i2c" }, { .compatible = "rockchip,rk3288-i2c" }, + { .compatible = "rockchip,rk3399-i2c" }, { } }; -- cgit v1.3.1 From 97fbf26d79701431b4dad1d4eae9d9f837b254cb Mon Sep 17 00:00:00 2001 From: Thomas Schaefer Date: Tue, 28 Mar 2017 11:29:56 -0700 Subject: drivers: ddr: fsl: fix unused-const-variable warnings Depending on DDR configuration, gcc-6.x will show up unused-const- variable messages. Use __maybe_unused specifier for all dynamic_odt variable definitions to remove these warnings. Memory footprint will not increase as gcc will optimize out unused constants. Signed-off-by: Thomas Schaefer Signed-off-by: York Sun --- drivers/ddr/fsl/options.c | 72 +++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c index d6a8fcb216a..1b81a7a2500 100644 --- a/drivers/ddr/fsl/options.c +++ b/drivers/ddr/fsl/options.c @@ -33,7 +33,7 @@ struct dynamic_odt { /* Quad rank is not verified yet due availability. * Replacing 20 OHM with 34 OHM since DDR4 doesn't have 20 OHM option */ -static const struct dynamic_odt single_Q[4] = { +static __maybe_unused const struct dynamic_odt single_Q[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS_AND_OTHER_DIMM, @@ -60,7 +60,7 @@ static const struct dynamic_odt single_Q[4] = { } }; -static const struct dynamic_odt single_D[4] = { +static __maybe_unused const struct dynamic_odt single_D[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -77,7 +77,7 @@ static const struct dynamic_odt single_D[4] = { {0, 0, 0, 0} }; -static const struct dynamic_odt single_S[4] = { +static __maybe_unused const struct dynamic_odt single_S[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -89,7 +89,7 @@ static const struct dynamic_odt single_S[4] = { {0, 0, 0, 0}, }; -static const struct dynamic_odt dual_DD[4] = { +static __maybe_unused const struct dynamic_odt dual_DD[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -116,7 +116,7 @@ static const struct dynamic_odt dual_DD[4] = { } }; -static const struct dynamic_odt dual_DS[4] = { +static __maybe_unused const struct dynamic_odt dual_DS[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -137,7 +137,7 @@ static const struct dynamic_odt dual_DS[4] = { }, {0, 0, 0, 0} }; -static const struct dynamic_odt dual_SD[4] = { +static __maybe_unused const struct dynamic_odt dual_SD[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_ALL, @@ -159,7 +159,7 @@ static const struct dynamic_odt dual_SD[4] = { } }; -static const struct dynamic_odt dual_SS[4] = { +static __maybe_unused const struct dynamic_odt dual_SS[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_ALL, @@ -176,7 +176,7 @@ static const struct dynamic_odt dual_SS[4] = { {0, 0, 0, 0} }; -static const struct dynamic_odt dual_D0[4] = { +static __maybe_unused const struct dynamic_odt dual_D0[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -193,7 +193,7 @@ static const struct dynamic_odt dual_D0[4] = { {0, 0, 0, 0} }; -static const struct dynamic_odt dual_0D[4] = { +static __maybe_unused const struct dynamic_odt dual_0D[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, { /* cs2 */ @@ -210,7 +210,7 @@ static const struct dynamic_odt dual_0D[4] = { } }; -static const struct dynamic_odt dual_S0[4] = { +static __maybe_unused const struct dynamic_odt dual_S0[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS, @@ -223,7 +223,7 @@ static const struct dynamic_odt dual_S0[4] = { }; -static const struct dynamic_odt dual_0S[4] = { +static __maybe_unused const struct dynamic_odt dual_0S[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, { /* cs2 */ @@ -236,7 +236,7 @@ static const struct dynamic_odt dual_0S[4] = { }; -static const struct dynamic_odt odt_unknown[4] = { +static __maybe_unused const struct dynamic_odt odt_unknown[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS, @@ -263,7 +263,7 @@ static const struct dynamic_odt odt_unknown[4] = { } }; #elif defined(CONFIG_SYS_FSL_DDR3) -static const struct dynamic_odt single_Q[4] = { +static __maybe_unused const struct dynamic_odt single_Q[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS_AND_OTHER_DIMM, @@ -290,7 +290,7 @@ static const struct dynamic_odt single_Q[4] = { } }; -static const struct dynamic_odt single_D[4] = { +static __maybe_unused const struct dynamic_odt single_D[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -307,7 +307,7 @@ static const struct dynamic_odt single_D[4] = { {0, 0, 0, 0} }; -static const struct dynamic_odt single_S[4] = { +static __maybe_unused const struct dynamic_odt single_S[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -319,7 +319,7 @@ static const struct dynamic_odt single_S[4] = { {0, 0, 0, 0}, }; -static const struct dynamic_odt dual_DD[4] = { +static __maybe_unused const struct dynamic_odt dual_DD[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -346,7 +346,7 @@ static const struct dynamic_odt dual_DD[4] = { } }; -static const struct dynamic_odt dual_DS[4] = { +static __maybe_unused const struct dynamic_odt dual_DS[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -367,7 +367,7 @@ static const struct dynamic_odt dual_DS[4] = { }, {0, 0, 0, 0} }; -static const struct dynamic_odt dual_SD[4] = { +static __maybe_unused const struct dynamic_odt dual_SD[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_ALL, @@ -389,7 +389,7 @@ static const struct dynamic_odt dual_SD[4] = { } }; -static const struct dynamic_odt dual_SS[4] = { +static __maybe_unused const struct dynamic_odt dual_SS[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_ALL, @@ -406,7 +406,7 @@ static const struct dynamic_odt dual_SS[4] = { {0, 0, 0, 0} }; -static const struct dynamic_odt dual_D0[4] = { +static __maybe_unused const struct dynamic_odt dual_D0[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_SAME_DIMM, @@ -423,7 +423,7 @@ static const struct dynamic_odt dual_D0[4] = { {0, 0, 0, 0} }; -static const struct dynamic_odt dual_0D[4] = { +static __maybe_unused const struct dynamic_odt dual_0D[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, { /* cs2 */ @@ -440,7 +440,7 @@ static const struct dynamic_odt dual_0D[4] = { } }; -static const struct dynamic_odt dual_S0[4] = { +static __maybe_unused const struct dynamic_odt dual_S0[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS, @@ -453,7 +453,7 @@ static const struct dynamic_odt dual_S0[4] = { }; -static const struct dynamic_odt dual_0S[4] = { +static __maybe_unused const struct dynamic_odt dual_0S[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, { /* cs2 */ @@ -466,7 +466,7 @@ static const struct dynamic_odt dual_0S[4] = { }; -static const struct dynamic_odt odt_unknown[4] = { +static __maybe_unused const struct dynamic_odt odt_unknown[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS, @@ -493,14 +493,14 @@ static const struct dynamic_odt odt_unknown[4] = { } }; #else /* CONFIG_SYS_FSL_DDR3 */ -static const struct dynamic_odt single_Q[4] = { +static __maybe_unused const struct dynamic_odt single_Q[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} }; -static const struct dynamic_odt single_D[4] = { +static __maybe_unused const struct dynamic_odt single_D[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -517,7 +517,7 @@ static const struct dynamic_odt single_D[4] = { {0, 0, 0, 0} }; -static const struct dynamic_odt single_S[4] = { +static __maybe_unused const struct dynamic_odt single_S[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -529,7 +529,7 @@ static const struct dynamic_odt single_S[4] = { {0, 0, 0, 0}, }; -static const struct dynamic_odt dual_DD[4] = { +static __maybe_unused const struct dynamic_odt dual_DD[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_OTHER_DIMM, @@ -556,7 +556,7 @@ static const struct dynamic_odt dual_DD[4] = { } }; -static const struct dynamic_odt dual_DS[4] = { +static __maybe_unused const struct dynamic_odt dual_DS[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_OTHER_DIMM, @@ -578,7 +578,7 @@ static const struct dynamic_odt dual_DS[4] = { {0, 0, 0, 0} }; -static const struct dynamic_odt dual_SD[4] = { +static __maybe_unused const struct dynamic_odt dual_SD[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_OTHER_DIMM, @@ -600,7 +600,7 @@ static const struct dynamic_odt dual_SD[4] = { } }; -static const struct dynamic_odt dual_SS[4] = { +static __maybe_unused const struct dynamic_odt dual_SS[4] = { { /* cs0 */ FSL_DDR_ODT_OTHER_DIMM, FSL_DDR_ODT_OTHER_DIMM, @@ -617,7 +617,7 @@ static const struct dynamic_odt dual_SS[4] = { {0, 0, 0, 0} }; -static const struct dynamic_odt dual_D0[4] = { +static __maybe_unused const struct dynamic_odt dual_D0[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_ALL, @@ -634,7 +634,7 @@ static const struct dynamic_odt dual_D0[4] = { {0, 0, 0, 0} }; -static const struct dynamic_odt dual_0D[4] = { +static __maybe_unused const struct dynamic_odt dual_0D[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, { /* cs2 */ @@ -651,7 +651,7 @@ static const struct dynamic_odt dual_0D[4] = { } }; -static const struct dynamic_odt dual_S0[4] = { +static __maybe_unused const struct dynamic_odt dual_S0[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS, @@ -664,7 +664,7 @@ static const struct dynamic_odt dual_S0[4] = { }; -static const struct dynamic_odt dual_0S[4] = { +static __maybe_unused const struct dynamic_odt dual_0S[4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, { /* cs2 */ @@ -677,7 +677,7 @@ static const struct dynamic_odt dual_0S[4] = { }; -static const struct dynamic_odt odt_unknown[4] = { +static __maybe_unused const struct dynamic_odt odt_unknown[4] = { { /* cs0 */ FSL_DDR_ODT_NEVER, FSL_DDR_ODT_CS, -- cgit v1.3.1 From 511fc86d0b1b603532056c663c22b91056908755 Mon Sep 17 00:00:00 2001 From: Ruchika Gupta Date: Mon, 17 Apr 2017 18:07:19 +0530 Subject: arm: ls1046ardb: Add SD secure boot target - Add SD secure boot target for ls1046ardb. - Change the u-boot size defined by a macro for copying the main U-Boot by SPL to also include the u-boot Secure Boot header size as header is appended to u-boot image. So header will also be copied from SD to DDR. - CONFIG_MAX_SPL_SIZE is limited to 90KB. SPL is copied to OCRAM (128K) where 32K are reserved for use by boot ROM and 6K for the header. - Reduce the size of CAAM driver for SPL Blobification functions and descriptors, that are not required at the time of SPL are disabled. Further error code conversion to strings is disabled for SPL build. Signed-off-by: Vinitha Pillai Signed-off-by: Sumit Garg Signed-off-by: Ruchika Gupta Reviewed-by: York Sun --- arch/arm/include/asm/fsl_secure_boot.h | 2 +- board/freescale/ls1046ardb/MAINTAINERS | 6 ++++ configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig | 45 +++++++++++++++++++++++++ drivers/crypto/fsl/jobdesc.c | 4 +-- drivers/crypto/fsl/jr.c | 19 ++++++----- include/configs/ls1046a_common.h | 16 +++++++-- 6 files changed, 78 insertions(+), 14 deletions(-) create mode 100644 configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig (limited to 'drivers') diff --git a/arch/arm/include/asm/fsl_secure_boot.h b/arch/arm/include/asm/fsl_secure_boot.h index 1fd09f205ae..7bff8b7561e 100644 --- a/arch/arm/include/asm/fsl_secure_boot.h +++ b/arch/arm/include/asm/fsl_secure_boot.h @@ -88,7 +88,7 @@ /* For SD boot address and size are assigned in terms of sector * offset and no. of sectors respectively. */ -#if defined(CONFIG_LS1043A) +#if defined(CONFIG_LS1043A) || defined(CONFIG_ARCH_LS1046A) #define CONFIG_BS_HDR_ADDR_DEVICE 0x00000920 #else #define CONFIG_BS_HDR_ADDR_DEVICE 0x00000900 diff --git a/board/freescale/ls1046ardb/MAINTAINERS b/board/freescale/ls1046ardb/MAINTAINERS index 758ff9d5723..79a2290974f 100644 --- a/board/freescale/ls1046ardb/MAINTAINERS +++ b/board/freescale/ls1046ardb/MAINTAINERS @@ -8,6 +8,12 @@ F: configs/ls1046ardb_qspi_defconfig F: configs/ls1046ardb_sdcard_defconfig F: configs/ls1046ardb_emmc_defconfig +LS1046A_SECURE_BOOT BOARD +M: Ruchika Gupta +S: Maintained +F: configs/ls1046ardb_SECURE_BOOT_defconfig +F: configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig + M: Sumit Garg S: Maintained F: configs/ls1046ardb_qspi_SECURE_BOOT_defconfig diff --git a/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig b/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig new file mode 100644 index 00000000000..a41ec80d3ad --- /dev/null +++ b/configs/ls1046ardb_sdcard_SECURE_BOOT_defconfig @@ -0,0 +1,45 @@ +CONFIG_ARM=y +CONFIG_TARGET_LS1046ARDB=y +CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1046a-rdb" +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,SPL_FSL_PBL" +CONFIG_SECURE_BOOT=y +CONFIG_SD_BOOT=y +CONFIG_BOOTDELAY=10 +CONFIG_SPL=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x110 +CONFIG_HUSH_PARSER=y +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_I2C=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_FAT=y +# CONFIG_SPL_EFI_PARTITION is not set +CONFIG_OF_CONTROL=y +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPI_FLASH=y +CONFIG_NETDEVICES=y +CONFIG_E1000=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_DM_PCI_COMPAT=y +CONFIG_PCIE_LAYERSCAPE=y +CONFIG_SYS_NS16550=y +CONFIG_DM_SPI=y +CONFIG_FSL_QSPI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_RSA=y +CONFIG_SPL_RSA=y +CONFIG_SPL_CRYPTO_SUPPORT=y +CONFIG_SPL_HASH_SUPPORT=y diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c index 6125bbb558d..375ff9d0e38 100644 --- a/drivers/crypto/fsl/jobdesc.c +++ b/drivers/crypto/fsl/jobdesc.c @@ -204,7 +204,7 @@ void inline_cnstr_jobdesc_hash(uint32_t *desc, append_store(desc, dma_addr_out, storelen, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT); } - +#ifndef CONFIG_SPL_BUILD void inline_cnstr_jobdesc_blob_encap(uint32_t *desc, uint8_t *key_idnfr, uint8_t *plain_txt, uint8_t *enc_blob, uint32_t in_sz) @@ -252,7 +252,7 @@ void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr, append_operation(desc, OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB); } - +#endif /* * Descriptor to instantiate RNG State Handle 0 in normal mode and * load the JDKEK, TDKEK and TDSK registers diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index 1b882291e4f..163e7299610 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -342,7 +342,9 @@ static void desc_done(uint32_t status, void *arg) { struct result *x = arg; x->status = status; +#ifndef CONFIG_SPL_BUILD caam_jr_strstatus(status); +#endif x->done = 1; } @@ -436,7 +438,11 @@ static inline int sec_reset_idx(uint8_t sec_idx) return 0; } - +int sec_reset(void) +{ + return sec_reset_idx(0); +} +#ifndef CONFIG_SPL_BUILD static int instantiate_rng(uint8_t sec_idx) { struct result op; @@ -472,11 +478,6 @@ static int instantiate_rng(uint8_t sec_idx) return ret; } -int sec_reset(void) -{ - return sec_reset_idx(0); -} - static u8 get_rng_vid(uint8_t sec_idx) { ccsr_sec_t *sec = (void *)SEC_ADDR(sec_idx); @@ -561,7 +562,7 @@ static int rng_init(uint8_t sec_idx) return ret; } - +#endif int sec_init_idx(uint8_t sec_idx) { ccsr_sec_t *sec = (void *)SEC_ADDR(sec_idx); @@ -634,7 +635,7 @@ int sec_init_idx(uint8_t sec_idx) pamu_enable(); #endif - +#ifndef CONFIG_SPL_BUILD if (get_rng_vid(sec_idx) >= 4) { if (rng_init(sec_idx) < 0) { printf("SEC%u: RNG instantiation failed\n", sec_idx); @@ -642,7 +643,7 @@ int sec_init_idx(uint8_t sec_idx) } printf("SEC%u: RNG instantiated\n", sec_idx); } - +#endif return ret; } diff --git a/include/configs/ls1046a_common.h b/include/configs/ls1046a_common.h index 164a5f38841..957ffd36347 100644 --- a/include/configs/ls1046a_common.h +++ b/include/configs/ls1046a_common.h @@ -85,7 +85,19 @@ #define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SPL_BSS_START_ADDR + \ CONFIG_SPL_BSS_MAX_SIZE) #define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 -#define CONFIG_SYS_MONITOR_LEN 0xa0000 + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_U_BOOT_HDR_SIZE (16 << 10) +/* + * HDR would be appended at end of image and copied to DDR along + * with U-Boot image. Here u-boot max. size is 512K. So if binary + * size increases then increase this size in case of secure boot as + * it uses raw u-boot image instead of fit image. + */ +#define CONFIG_SYS_MONITOR_LEN (0x100000 + CONFIG_U_BOOT_HDR_SIZE) +#else +#define CONFIG_SYS_MONITOR_LEN 0x100000 +#endif /* ifdef CONFIG_SECURE_BOOT */ #endif /* NAND SPL */ @@ -105,7 +117,7 @@ #define CONFIG_SPL_NAND_SUPPORT #define CONFIG_SPL_DRIVERS_MISC_SUPPORT #define CONFIG_SPL_TEXT_BASE 0x10000000 -#define CONFIG_SPL_MAX_SIZE 0x1d000 /* 116 KiB */ +#define CONFIG_SPL_MAX_SIZE 0x17000 /* 90 KiB */ #define CONFIG_SPL_STACK 0x1001f000 #define CONFIG_SYS_NAND_U_BOOT_DST CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE -- cgit v1.3.1 From 4a3ab193222d495ad55b3902fde2654489ad767b Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 27 Mar 2017 11:41:01 -0700 Subject: armv8: ls2080a: Drop macro CONFIG_LS2080A Use CONFIG_ARCH_LS2080A instead. Signed-off-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/Makefile | 2 +- arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 6 +++--- arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S | 2 +- arch/arm/cpu/armv8/fsl-layerscape/spl.c | 2 +- arch/arm/include/asm/arch-fsl-layerscape/config.h | 2 +- arch/arm/include/asm/arch-fsl-layerscape/cpu.h | 2 +- arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h | 2 +- arch/arm/include/asm/fsl_secure_boot.h | 2 +- configs/ls2080a_emu_defconfig | 2 +- configs/ls2080a_simu_defconfig | 2 +- configs/ls2080aqds_SECURE_BOOT_defconfig | 1 - configs/ls2080aqds_defconfig | 1 - configs/ls2080aqds_nand_defconfig | 2 +- configs/ls2080aqds_qspi_defconfig | 2 +- configs/ls2080ardb_SECURE_BOOT_defconfig | 1 - configs/ls2080ardb_defconfig | 1 - configs/ls2080ardb_nand_defconfig | 2 +- drivers/crypto/fsl/jr.c | 2 +- drivers/net/ldpaa_eth/Makefile | 2 +- include/linux/usb/xhci-fsl.h | 2 +- scripts/config_whitelist.txt | 1 - 21 files changed, 18 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Makefile b/arch/arm/cpu/armv8/fsl-layerscape/Makefile index c9ab93e3d7c..04354d7063b 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Makefile +++ b/arch/arm/cpu/armv8/fsl-layerscape/Makefile @@ -22,7 +22,7 @@ obj-$(CONFIG_SYS_HAS_SERDES) += fsl_lsch2_serdes.o endif endif -ifneq ($(CONFIG_LS2080A),) +ifneq ($(CONFIG_ARCH_LS2080A),) obj-$(CONFIG_SYS_HAS_SERDES) += ls2080a_serdes.o endif diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index d446527616c..c24f3f173c0 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -92,7 +92,7 @@ static inline void early_mmu_setup(void) static void fix_pcie_mmu_map(void) { -#ifdef CONFIG_LS2080A +#ifdef CONFIG_ARCH_LS2080A unsigned int i; u32 svr, ver; struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); @@ -523,7 +523,7 @@ int timer_init(void) #ifdef CONFIG_FSL_LSCH3 u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR; #endif -#ifdef CONFIG_LS2080A +#ifdef CONFIG_ARCH_LS2080A u32 __iomem *pctbenr = (u32 *)FSL_PMU_PCTBENR_OFFSET; u32 svr_dev_id; #endif @@ -541,7 +541,7 @@ int timer_init(void) out_le32(cltbenr, 0xf); #endif -#ifdef CONFIG_LS2080A +#ifdef CONFIG_ARCH_LS2080A /* * In certain Layerscape SoCs, the clock for each core's * has an enable bit in the PMU Physical Core Time Base Enable diff --git a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S index a2185f2def2..fa6b6e624a1 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S +++ b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S @@ -76,7 +76,7 @@ ENTRY(lowlevel_init) #ifdef CONFIG_FSL_LSCH3 /* Set Wuo bit for RN-I 20 */ -#ifdef CONFIG_LS2080A +#ifdef CONFIG_ARCH_LS2080A ldr x0, =CCI_AUX_CONTROL_BASE(20) ldr x1, =0x00000010 bl ccn504_set_aux diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c index dfacf98e889..eb730e84a46 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c @@ -65,7 +65,7 @@ void board_init_f(ulong dummy) memset((void *)gd, 0, sizeof(gd_t)); board_early_init_f(); timer_init(); -#ifdef CONFIG_LS2080A +#ifdef CONFIG_ARCH_LS2080A env_init(); #endif get_clocks(); diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h index 4db11b646e0..fb18440996a 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/config.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h @@ -18,7 +18,7 @@ */ #define CONFIG_SYS_MEM_RESERVE_SECURE (2048 * 1024) /* 2MB */ -#ifdef CONFIG_LS2080A +#ifdef CONFIG_ARCH_LS2080A #define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 1, 4, 4 } #define SRDS_MAX_LANES 8 #define CONFIG_SYS_PAGE_SIZE 0x10000 diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h index bcf3e3863e6..95c3e2fc086 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h @@ -249,7 +249,7 @@ static struct mm_region final_map[] = { PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, -#ifdef CONFIG_LS2080A +#ifdef CONFIG_ARCH_LS2080A { CONFIG_SYS_PCIE4_PHYS_ADDR, CONFIG_SYS_PCIE4_PHYS_ADDR, CONFIG_SYS_PCIE4_PHYS_SIZE, PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | diff --git a/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h b/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h index 70181c5077c..a8f9a505016 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/fsl_serdes.h @@ -9,7 +9,7 @@ #include -#ifdef CONFIG_LS2080A +#ifdef CONFIG_ARCH_LS2080A enum srds_prtcl { /* * Nobody will check whether the device 'NONE' has been configured, diff --git a/arch/arm/include/asm/fsl_secure_boot.h b/arch/arm/include/asm/fsl_secure_boot.h index 7bff8b7561e..2799a604ffb 100644 --- a/arch/arm/include/asm/fsl_secure_boot.h +++ b/arch/arm/include/asm/fsl_secure_boot.h @@ -55,7 +55,7 @@ #define CONFIG_ESBC_ADDR_64BIT #endif -#ifdef CONFIG_LS2080A +#ifdef CONFIG_ARCH_LS2080A #define CONFIG_EXTRA_ENV \ "setenv fdt_high 0xa0000000;" \ "setenv initrd_high 0xcfffffff;" \ diff --git a/configs/ls2080a_emu_defconfig b/configs/ls2080a_emu_defconfig index edf76851a30..6211b6b5af2 100644 --- a/configs/ls2080a_emu_defconfig +++ b/configs/ls2080a_emu_defconfig @@ -5,7 +5,7 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y -CONFIG_SYS_EXTRA_OPTIONS="EMU,LS2080A" +CONFIG_SYS_EXTRA_OPTIONS="EMU" CONFIG_BOOTDELAY=10 # CONFIG_DISPLAY_BOARDINFO is not set # CONFIG_CMD_CONSOLE is not set diff --git a/configs/ls2080a_simu_defconfig b/configs/ls2080a_simu_defconfig index 5cc9316a20a..b6f7709af2b 100644 --- a/configs/ls2080a_simu_defconfig +++ b/configs/ls2080a_simu_defconfig @@ -5,7 +5,7 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y -CONFIG_SYS_EXTRA_OPTIONS="SIMU, LS2080A" +CONFIG_SYS_EXTRA_OPTIONS="SIMU" CONFIG_BOOTDELAY=10 # CONFIG_DISPLAY_BOARDINFO is not set # CONFIG_CMD_CONSOLE is not set diff --git a/configs/ls2080aqds_SECURE_BOOT_defconfig b/configs/ls2080aqds_SECURE_BOOT_defconfig index 6ab9703c45e..45e5d87f361 100644 --- a/configs/ls2080aqds_SECURE_BOOT_defconfig +++ b/configs/ls2080aqds_SECURE_BOOT_defconfig @@ -7,7 +7,6 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y -CONFIG_SYS_EXTRA_OPTIONS="LS2080A" CONFIG_BOOTDELAY=10 CONFIG_CMD_GREPENV=y CONFIG_CMD_GPT=y diff --git a/configs/ls2080aqds_defconfig b/configs/ls2080aqds_defconfig index fb9a3e4041f..770dea06056 100644 --- a/configs/ls2080aqds_defconfig +++ b/configs/ls2080aqds_defconfig @@ -7,7 +7,6 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y -CONFIG_SYS_EXTRA_OPTIONS="LS2080A" CONFIG_BOOTDELAY=10 CONFIG_CMD_GREPENV=y CONFIG_CMD_GPT=y diff --git a/configs/ls2080aqds_nand_defconfig b/configs/ls2080aqds_nand_defconfig index 2a649c576d3..aa4f1345586 100644 --- a/configs/ls2080aqds_nand_defconfig +++ b/configs/ls2080aqds_nand_defconfig @@ -10,7 +10,7 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y -CONFIG_SYS_EXTRA_OPTIONS="NAND, LS2080A" +CONFIG_SYS_EXTRA_OPTIONS="NAND" CONFIG_BOOTDELAY=10 CONFIG_SPL=y CONFIG_SPL_ENV_SUPPORT=y diff --git a/configs/ls2080aqds_qspi_defconfig b/configs/ls2080aqds_qspi_defconfig index a81e7c69452..6deb0acbd23 100644 --- a/configs/ls2080aqds_qspi_defconfig +++ b/configs/ls2080aqds_qspi_defconfig @@ -5,7 +5,7 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y -CONFIG_SYS_EXTRA_OPTIONS="QSPI_BOOT,LS2080A" +CONFIG_SYS_EXTRA_OPTIONS="QSPI_BOOT" CONFIG_QSPI_BOOT=y CONFIG_BOOTDELAY=10 CONFIG_CMD_GREPENV=y diff --git a/configs/ls2080ardb_SECURE_BOOT_defconfig b/configs/ls2080ardb_SECURE_BOOT_defconfig index 70baf0efc8d..19c9db5ae83 100644 --- a/configs/ls2080ardb_SECURE_BOOT_defconfig +++ b/configs/ls2080ardb_SECURE_BOOT_defconfig @@ -7,7 +7,6 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y -CONFIG_SYS_EXTRA_OPTIONS="LS2080A" CONFIG_BOOTDELAY=10 CONFIG_CMD_GREPENV=y CONFIG_CMD_GPT=y diff --git a/configs/ls2080ardb_defconfig b/configs/ls2080ardb_defconfig index a1e552d69a3..e0cb7f898e7 100644 --- a/configs/ls2080ardb_defconfig +++ b/configs/ls2080ardb_defconfig @@ -7,7 +7,6 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y -CONFIG_SYS_EXTRA_OPTIONS="LS2080A" CONFIG_BOOTDELAY=10 CONFIG_CMD_GREPENV=y CONFIG_CMD_GPT=y diff --git a/configs/ls2080ardb_nand_defconfig b/configs/ls2080ardb_nand_defconfig index 81987fe6b3a..cd57374a4e7 100644 --- a/configs/ls2080ardb_nand_defconfig +++ b/configs/ls2080ardb_nand_defconfig @@ -10,7 +10,7 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y CONFIG_OF_STDOUT_VIA_ALIAS=y -CONFIG_SYS_EXTRA_OPTIONS="NAND, LS2080A" +CONFIG_SYS_EXTRA_OPTIONS="NAND" CONFIG_BOOTDELAY=10 CONFIG_SPL=y CONFIG_SPL_ENV_SUPPORT=y diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index 163e7299610..f4f6c16df7c 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -587,7 +587,7 @@ int sec_init_idx(uint8_t sec_idx) * For AXI Read - Cacheable, Read allocate * Only For LS2080a, to solve CAAM coherency issues */ -#ifdef CONFIG_LS2080A +#ifdef CONFIG_ARCH_LS2080A mcr = (mcr & ~MCFGR_AWCACHE_MASK) | (0xb << MCFGR_AWCACHE_SHIFT); mcr = (mcr & ~MCFGR_ARCACHE_MASK) | (0x6 << MCFGR_ARCACHE_SHIFT); #else diff --git a/drivers/net/ldpaa_eth/Makefile b/drivers/net/ldpaa_eth/Makefile index 5587aa618df..08675ec6416 100644 --- a/drivers/net/ldpaa_eth/Makefile +++ b/drivers/net/ldpaa_eth/Makefile @@ -6,4 +6,4 @@ obj-y += ldpaa_wriop.o obj-y += ldpaa_eth.o -obj-$(CONFIG_LS2080A) += ls2080a.o +obj-$(CONFIG_ARCH_LS2080A) += ls2080a.o diff --git a/include/linux/usb/xhci-fsl.h b/include/linux/usb/xhci-fsl.h index 1fa31613bbd..23e5939f3b2 100644 --- a/include/linux/usb/xhci-fsl.h +++ b/include/linux/usb/xhci-fsl.h @@ -58,7 +58,7 @@ struct fsl_xhci { #define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_XHCI_USB1_ADDR #define CONFIG_SYS_FSL_XHCI_USB2_ADDR 0 #define CONFIG_SYS_FSL_XHCI_USB3_ADDR 0 -#elif defined(CONFIG_LS2080A) +#elif defined(CONFIG_ARCH_LS2080A) #define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_XHCI_USB1_ADDR #define CONFIG_SYS_FSL_XHCI_USB2_ADDR CONFIG_SYS_XHCI_USB2_ADDR #define CONFIG_SYS_FSL_XHCI_USB3_ADDR 0 diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index d487be72ffd..dd8abc0de19 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1700,7 +1700,6 @@ CONFIG_LQ038J7DH53 CONFIG_LS102XA CONFIG_LS102XA_STREAM_ID CONFIG_LS1043A -CONFIG_LS2080A CONFIG_LSCHLV2 CONFIG_LSXHL CONFIG_LUAN -- cgit v1.3.1 From c1303bfd7e14f5ee451f6aafeeca2d87ac1255d6 Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 27 Mar 2017 11:41:02 -0700 Subject: armv8: ls1043a: Drop macro CONFIG_LS1043A Use CONFIG_ARCH_LS1043A instead. Signed-off-by: York Sun --- arch/arm/cpu/armv8/fsl-layerscape/Makefile | 2 +- arch/arm/include/asm/arch-fsl-layerscape/config.h | 2 +- arch/arm/include/asm/fsl_secure_boot.h | 2 +- drivers/net/fm/Makefile | 2 +- include/configs/ls1043a_common.h | 1 - include/linux/usb/xhci-fsl.h | 2 +- scripts/config_whitelist.txt | 1 - 7 files changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Makefile b/arch/arm/cpu/armv8/fsl-layerscape/Makefile index 04354d7063b..e3ce0184d89 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Makefile +++ b/arch/arm/cpu/armv8/fsl-layerscape/Makefile @@ -26,7 +26,7 @@ ifneq ($(CONFIG_ARCH_LS2080A),) obj-$(CONFIG_SYS_HAS_SERDES) += ls2080a_serdes.o endif -ifneq ($(CONFIG_LS1043A),) +ifneq ($(CONFIG_ARCH_LS1043A),) obj-$(CONFIG_SYS_HAS_SERDES) += ls1043a_serdes.o obj-$(CONFIG_ARMV8_PSCI) += ls1043a_psci.o endif diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h index fb18440996a..93e6597d9e0 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/config.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h @@ -132,7 +132,7 @@ #define CONFIG_SYS_FSL_PEX_LUT_BE /* SoC related */ -#ifdef CONFIG_LS1043A +#ifdef CONFIG_ARCH_LS1043A #define CONFIG_SYS_FMAN_V3 #define CONFIG_SYS_NUM_FMAN 1 #define CONFIG_SYS_NUM_FM1_DTSEC 7 diff --git a/arch/arm/include/asm/fsl_secure_boot.h b/arch/arm/include/asm/fsl_secure_boot.h index 2799a604ffb..f5ca5d3b697 100644 --- a/arch/arm/include/asm/fsl_secure_boot.h +++ b/arch/arm/include/asm/fsl_secure_boot.h @@ -88,7 +88,7 @@ /* For SD boot address and size are assigned in terms of sector * offset and no. of sectors respectively. */ -#if defined(CONFIG_LS1043A) || defined(CONFIG_ARCH_LS1046A) +#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) #define CONFIG_BS_HDR_ADDR_DEVICE 0x00000920 #else #define CONFIG_BS_HDR_ADDR_DEVICE 0x00000900 diff --git a/drivers/net/fm/Makefile b/drivers/net/fm/Makefile index fa96bad902d..fc7a6da03bc 100644 --- a/drivers/net/fm/Makefile +++ b/drivers/net/fm/Makefile @@ -34,5 +34,5 @@ obj-$(CONFIG_ARCH_T4240) += t4240.o obj-$(CONFIG_ARCH_T4160) += t4240.o obj-$(CONFIG_ARCH_B4420) += b4860.o obj-$(CONFIG_ARCH_B4860) += b4860.o -obj-$(CONFIG_LS1043A) += ls1043.o +obj-$(CONFIG_ARCH_LS1043A) += ls1043.o obj-$(CONFIG_ARCH_LS1046A) += ls1046.o diff --git a/include/configs/ls1043a_common.h b/include/configs/ls1043a_common.h index 7b1d9bbbed5..e26924877d1 100644 --- a/include/configs/ls1043a_common.h +++ b/include/configs/ls1043a_common.h @@ -28,7 +28,6 @@ #define CONFIG_REMAKE_ELF #define CONFIG_FSL_LAYERSCAPE -#define CONFIG_LS1043A #define CONFIG_MP #define CONFIG_GICV2 diff --git a/include/linux/usb/xhci-fsl.h b/include/linux/usb/xhci-fsl.h index 23e5939f3b2..e0dff30f380 100644 --- a/include/linux/usb/xhci-fsl.h +++ b/include/linux/usb/xhci-fsl.h @@ -62,7 +62,7 @@ struct fsl_xhci { #define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_XHCI_USB1_ADDR #define CONFIG_SYS_FSL_XHCI_USB2_ADDR CONFIG_SYS_XHCI_USB2_ADDR #define CONFIG_SYS_FSL_XHCI_USB3_ADDR 0 -#elif defined(CONFIG_LS1043A) || defined(CONFIG_ARCH_LS1046A) +#elif defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) #define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_XHCI_USB1_ADDR #define CONFIG_SYS_FSL_XHCI_USB2_ADDR CONFIG_SYS_XHCI_USB2_ADDR #define CONFIG_SYS_FSL_XHCI_USB3_ADDR CONFIG_SYS_XHCI_USB3_ADDR diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index dd8abc0de19..b7b7a24d54b 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1699,7 +1699,6 @@ CONFIG_LPUART_32B_REG CONFIG_LQ038J7DH53 CONFIG_LS102XA CONFIG_LS102XA_STREAM_ID -CONFIG_LS1043A CONFIG_LSCHLV2 CONFIG_LSXHL CONFIG_LUAN -- cgit v1.3.1 From 73fb583829efb296ecdddb08c426e2261cb84d0a Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 27 Mar 2017 11:41:03 -0700 Subject: armv7: ls1021a: Drop macro CONFIG_LS102XA Use CONFIG_ARCH_LS1021A instead. Signed-off-by: York Sun --- arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/dts/Makefile | 2 +- arch/arm/include/asm/arch-ls102xa/config.h | 2 +- arch/arm/include/asm/config.h | 2 +- board/freescale/common/arm_sleep.c | 6 +++--- board/freescale/common/fsl_chain_of_trust.c | 2 +- board/freescale/common/fsl_validate.c | 2 +- drivers/i2c/mxc_i2c.c | 2 +- drivers/qe/qe.c | 6 +++--- drivers/usb/common/fsl-errata.c | 2 +- include/configs/ls1021aiot.h | 2 -- include/configs/ls1021aqds.h | 2 -- include/configs/ls1021atwr.h | 2 -- include/fsl_errata.h | 4 ++-- include/linux/immap_qe.h | 2 +- include/linux/usb/xhci-fsl.h | 2 +- include/tsec.h | 2 +- include/usb/ehci-ci.h | 2 +- scripts/config_whitelist.txt | 1 - 19 files changed, 20 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 02e8778be5b..999ab47065a 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -12,7 +12,7 @@ obj-y += cache_v7.o cache_v7_asm.o obj-y += cpu.o cp15.o obj-y += syslib.o -ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_MX7)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY)$(CONFIG_ARCH_SUNXI)$(CONFIG_ARCH_SOCFPGA)$(CONFIG_ARCH_MX7ULP)$(CONFIG_LS102XA),) +ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_MX7)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY)$(CONFIG_ARCH_SUNXI)$(CONFIG_ARCH_SOCFPGA)$(CONFIG_ARCH_MX7ULP)$(CONFIG_ARCH_LS1021A),) ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y) obj-y += lowlevel_init.o endif diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 68d2791c155..0ee42818f6b 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -166,7 +166,7 @@ dtb-$(CONFIG_TARGET_AM57XX_EVM) += am57xx-beagle-x15.dtb \ am571x-idk.dtb dtb-$(CONFIG_TARGET_STV0991) += stv0991.dtb -dtb-$(CONFIG_LS102XA) += ls1021a-qds-duart.dtb \ +dtb-$(CONFIG_ARCH_LS1021A) += ls1021a-qds-duart.dtb \ ls1021a-qds-lpuart.dtb \ ls1021a-twr-duart.dtb ls1021a-twr-lpuart.dtb \ ls1021a-iot-duart.dtb diff --git a/arch/arm/include/asm/arch-ls102xa/config.h b/arch/arm/include/asm/arch-ls102xa/config.h index 2f7233f2feb..5c4da0f0e35 100644 --- a/arch/arm/include/asm/arch-ls102xa/config.h +++ b/arch/arm/include/asm/arch-ls102xa/config.h @@ -108,7 +108,7 @@ #define DCU_LAYER_MAX_NUM 16 -#ifdef CONFIG_LS102XA +#ifdef CONFIG_ARCH_LS1021A #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 #define CONFIG_SYS_FSL_MAX_NUM_OF_SEC 1 #else diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 1ad221a9876..5674d37c04d 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -14,7 +14,7 @@ #define CONFIG_STATIC_RELA #endif -#if defined(CONFIG_LS102XA) || \ +#if defined(CONFIG_ARCH_LS1021A) || \ defined(CONFIG_CPU_PXA27X) || \ defined(CONFIG_CPU_MONAHANS) || \ defined(CONFIG_CPU_PXA25X) || \ diff --git a/board/freescale/common/arm_sleep.c b/board/freescale/common/arm_sleep.c index 16fd445306e..6ed5d9ef1fa 100644 --- a/board/freescale/common/arm_sleep.c +++ b/board/freescale/common/arm_sleep.c @@ -13,7 +13,7 @@ #endif #include -#if defined(CONFIG_LS102XA) +#if defined(CONFIG_ARCH_LS1021A) #include #endif @@ -66,7 +66,7 @@ static void dp_ddr_restore(void) *dst++ = *src++; } -#if defined(CONFIG_ARMV7_PSCI) && defined(CONFIG_LS102XA) +#if defined(CONFIG_ARMV7_PSCI) && defined(CONFIG_ARCH_LS1021A) void ls1_psci_resume_fixup(void) { u32 tmp; @@ -104,7 +104,7 @@ static void dp_resume_prepare(void) #ifdef CONFIG_U_QE u_qe_resume(); #endif -#if defined(CONFIG_ARMV7_PSCI) && defined(CONFIG_LS102XA) +#if defined(CONFIG_ARMV7_PSCI) && defined(CONFIG_ARCH_LS1021A) ls1_psci_resume_fixup(); #endif } diff --git a/board/freescale/common/fsl_chain_of_trust.c b/board/freescale/common/fsl_chain_of_trust.c index 438e7819576..aad1b93d140 100644 --- a/board/freescale/common/fsl_chain_of_trust.c +++ b/board/freescale/common/fsl_chain_of_trust.c @@ -22,7 +22,7 @@ #include #endif -#ifdef CONFIG_LS102XA +#ifdef CONFIG_ARCH_LS1021A #include #endif diff --git a/board/freescale/common/fsl_validate.c b/board/freescale/common/fsl_validate.c index 125655a37a2..ed48c5c8bd7 100644 --- a/board/freescale/common/fsl_validate.c +++ b/board/freescale/common/fsl_validate.c @@ -15,7 +15,7 @@ #include #include #include -#ifdef CONFIG_LS102XA +#ifdef CONFIG_ARCH_LS1021A #include #endif diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index eb789f5bff4..13ec0e63b10 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -589,7 +589,7 @@ static int bus_i2c_write(struct mxc_i2c_bus *i2c_bus, u8 chip, u32 addr, #endif static struct mxc_i2c_bus mxc_i2c_buses[] = { -#if defined(CONFIG_LS102XA) || defined(CONFIG_VF610) || \ +#if defined(CONFIG_ARCH_LS1021A) || defined(CONFIG_VF610) || \ defined(CONFIG_FSL_LAYERSCAPE) { 0, I2C1_BASE_ADDR, I2C_QUIRK_FLAG }, { 1, I2C2_BASE_ADDR, I2C_QUIRK_FLAG }, diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c index 4231594776a..4f0a27892f2 100644 --- a/drivers/qe/qe.c +++ b/drivers/qe/qe.c @@ -13,7 +13,7 @@ #include #include #include -#ifdef CONFIG_LS102XA +#ifdef CONFIG_ARCH_LS1021A #include #endif @@ -355,7 +355,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware) size_t length; const struct qe_header *hdr; #ifdef CONFIG_DEEP_SLEEP -#ifdef CONFIG_LS102XA +#ifdef CONFIG_ARCH_LS1021A struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; #else ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); @@ -494,7 +494,7 @@ int u_qe_upload_firmware(const struct qe_firmware *firmware) size_t length; const struct qe_header *hdr; #ifdef CONFIG_DEEP_SLEEP -#ifdef CONFIG_LS102XA +#ifdef CONFIG_ARCH_LS1021A struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; #else ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); diff --git a/drivers/usb/common/fsl-errata.c b/drivers/usb/common/fsl-errata.c index 6069c935c12..338ac08d8a7 100644 --- a/drivers/usb/common/fsl-errata.c +++ b/drivers/usb/common/fsl-errata.c @@ -204,7 +204,7 @@ bool has_erratum_a010151(void) case SVR_LS1043A: return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1); #endif -#ifdef CONFIG_LS102XA +#ifdef CONFIG_ARCH_LS1021A case SOC_VER_LS1020: case SOC_VER_LS1021: case SOC_VER_LS1022: diff --git a/include/configs/ls1021aiot.h b/include/configs/ls1021aiot.h index d8bbc802d2d..35d17b96f4a 100644 --- a/include/configs/ls1021aiot.h +++ b/include/configs/ls1021aiot.h @@ -7,8 +7,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_LS102XA - #define CONFIG_ARMV7_SECURE_BASE OCRAM_BASE_S_ADDR #define CONFIG_SYS_FSL_CLK diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index 97b81274b05..c3224c8c3f4 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -7,8 +7,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_LS102XA - #define CONFIG_ARMV7_PSCI_1_0 #define CONFIG_ARMV7_SECURE_BASE OCRAM_BASE_S_ADDR diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index a60b4b29902..1d0b4698bbf 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -7,8 +7,6 @@ #ifndef __CONFIG_H #define __CONFIG_H -#define CONFIG_LS102XA - #define CONFIG_ARMV7_PSCI_1_0 #define CONFIG_ARMV7_SECURE_BASE OCRAM_BASE_S_ADDR diff --git a/include/fsl_errata.h b/include/fsl_errata.h index 8441f91029c..89051aa7412 100644 --- a/include/fsl_errata.h +++ b/include/fsl_errata.h @@ -10,7 +10,7 @@ #include #if defined(CONFIG_PPC) #include -#elif defined(CONFIG_LS102XA) +#elif defined(CONFIG_ARCH_LS1021A) #include #elif defined(CONFIG_FSL_LAYERSCAPE) #include @@ -66,7 +66,7 @@ static inline bool has_erratum_a008378(void) switch (soc) { -#ifdef CONFIG_LS102XA +#ifdef CONFIG_ARCH_LS1021A case SOC_VER_LS1020: case SOC_VER_LS1021: case SOC_VER_LS1022: diff --git a/include/linux/immap_qe.h b/include/linux/immap_qe.h index 6d1f88ec2e1..d952efa8f45 100644 --- a/include/linux/immap_qe.h +++ b/include/linux/immap_qe.h @@ -24,7 +24,7 @@ #endif #endif -#ifdef CONFIG_LS102XA +#ifdef CONFIG_ARCH_LS1021A #define QE_MURAM_SIZE 0x6000UL #define MAX_QE_RISC 1 #define QE_NUM_OF_SNUM 28 diff --git a/include/linux/usb/xhci-fsl.h b/include/linux/usb/xhci-fsl.h index e0dff30f380..bd54089722f 100644 --- a/include/linux/usb/xhci-fsl.h +++ b/include/linux/usb/xhci-fsl.h @@ -54,7 +54,7 @@ struct fsl_xhci { struct dwc3 *dwc3_reg; }; -#if defined(CONFIG_LS102XA) || defined(CONFIG_ARCH_LS1012A) +#if defined(CONFIG_ARCH_LS1021A) || defined(CONFIG_ARCH_LS1012A) #define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_XHCI_USB1_ADDR #define CONFIG_SYS_FSL_XHCI_USB2_ADDR 0 #define CONFIG_SYS_FSL_XHCI_USB3_ADDR 0 diff --git a/include/tsec.h b/include/tsec.h index fb27edf2250..e99a7fa8782 100644 --- a/include/tsec.h +++ b/include/tsec.h @@ -20,7 +20,7 @@ #ifndef CONFIG_DM_ETH -#ifdef CONFIG_LS102XA +#ifdef CONFIG_ARCH_LS1021A #define TSEC_SIZE 0x40000 #define TSEC_MDIO_OFFSET 0x40000 #else diff --git a/include/usb/ehci-ci.h b/include/usb/ehci-ci.h index 882aed4a5f0..8f3437a208c 100644 --- a/include/usb/ehci-ci.h +++ b/include/usb/ehci-ci.h @@ -159,7 +159,7 @@ #elif defined(CONFIG_MPC512X) #define CONFIG_SYS_FSL_USB1_ADDR CONFIG_SYS_MPC512x_USB1_ADDR #define CONFIG_SYS_FSL_USB2_ADDR 0 -#elif defined(CONFIG_LS102XA) +#elif defined(CONFIG_ARCH_LS1021A) #define CONFIG_SYS_FSL_USB1_ADDR CONFIG_SYS_EHCI_USB1_ADDR #define CONFIG_SYS_FSL_USB2_ADDR 0 #endif diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index b7b7a24d54b..5e515d215c1 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1697,7 +1697,6 @@ CONFIG_LPC_IO_BASE CONFIG_LPUART CONFIG_LPUART_32B_REG CONFIG_LQ038J7DH53 -CONFIG_LS102XA CONFIG_LS102XA_STREAM_ID CONFIG_LSCHLV2 CONFIG_LSXHL -- cgit v1.3.1 From 90d6500c0f90dd6e9aa770a5d8faf88bb34440ea Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 14 Apr 2017 10:55:00 +0900 Subject: drivers: remove Blackfin specific drivers These drivers have no user since commit ea3310e8aafa ("Blackfin: Remove"). Signed-off-by: Masahiro Yamada Reviewed-by: Simon Glass Acked-by: Michal Simek Acked-by: Jaehoon Chung --- drivers/block/Makefile | 1 - drivers/block/pata_bfin.c | 1209 ------------------------------------------ drivers/block/pata_bfin.h | 170 ------ drivers/mmc/Makefile | 1 - drivers/mmc/bfin_sdh.c | 306 ----------- drivers/mtd/nand/Makefile | 1 - drivers/mtd/nand/bfin_nand.c | 394 -------------- drivers/net/Makefile | 1 - drivers/net/bfin_mac.c | 519 ------------------ drivers/net/bfin_mac.h | 65 --- drivers/rtc/Makefile | 1 - drivers/rtc/bfin_rtc.c | 121 ----- drivers/watchdog/Makefile | 1 - drivers/watchdog/bfin_wdt.c | 27 - 14 files changed, 2817 deletions(-) delete mode 100644 drivers/block/pata_bfin.c delete mode 100644 drivers/block/pata_bfin.h delete mode 100644 drivers/mmc/bfin_sdh.c delete mode 100644 drivers/mtd/nand/bfin_nand.c delete mode 100644 drivers/net/bfin_mac.c delete mode 100644 drivers/net/bfin_mac.h delete mode 100644 drivers/rtc/bfin_rtc.c delete mode 100644 drivers/watchdog/bfin_wdt.c (limited to 'drivers') diff --git a/drivers/block/Makefile b/drivers/block/Makefile index a72feecd545..f415b3371bb 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_IDE_FTIDE020) += ftide020.o obj-$(CONFIG_LIBATA) += libata.o obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o obj-$(CONFIG_MX51_PATA) += mxc_ata.o -obj-$(CONFIG_PATA_BFIN) += pata_bfin.o obj-$(CONFIG_SATA_CEVA) += sata_ceva.o obj-$(CONFIG_SATA_DWC) += sata_dwc.o obj-$(CONFIG_SATA_MV) += sata_mv.o diff --git a/drivers/block/pata_bfin.c b/drivers/block/pata_bfin.c deleted file mode 100644 index 36a15125ad2..00000000000 --- a/drivers/block/pata_bfin.c +++ /dev/null @@ -1,1209 +0,0 @@ -/* - * Driver for Blackfin on-chip ATAPI controller. - * - * Enter bugs at http://blackfin.uclinux.org/ - * - * Copyright (c) 2008 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pata_bfin.h" - -static struct ata_port port[CONFIG_SYS_SATA_MAX_DEVICE]; - -/** - * PIO Mode - Frequency compatibility - */ -/* mode: 0 1 2 3 4 */ -static const u32 pio_fsclk[] = -{ 33333333, 33333333, 33333333, 33333333, 33333333 }; - -/** - * MDMA Mode - Frequency compatibility - */ -/* mode: 0 1 2 */ -static const u32 mdma_fsclk[] = { 33333333, 33333333, 33333333 }; - -/** - * UDMA Mode - Frequency compatibility - * - * UDMA5 - 100 MB/s - SCLK = 133 MHz - * UDMA4 - 66 MB/s - SCLK >= 80 MHz - * UDMA3 - 44.4 MB/s - SCLK >= 50 MHz - * UDMA2 - 33 MB/s - SCLK >= 40 MHz - */ -/* mode: 0 1 2 3 4 5 */ -static const u32 udma_fsclk[] = -{ 33333333, 33333333, 40000000, 50000000, 80000000, 133333333 }; - -/** - * Register transfer timing table - */ -/* mode: 0 1 2 3 4 */ -/* Cycle Time */ -static const u32 reg_t0min[] = { 600, 383, 330, 180, 120 }; -/* DIOR/DIOW to end cycle */ -static const u32 reg_t2min[] = { 290, 290, 290, 70, 25 }; -/* DIOR/DIOW asserted pulse width */ -static const u32 reg_teocmin[] = { 290, 290, 290, 80, 70 }; - -/** - * PIO timing table - */ -/* mode: 0 1 2 3 4 */ -/* Cycle Time */ -static const u32 pio_t0min[] = { 600, 383, 240, 180, 120 }; -/* Address valid to DIOR/DIORW */ -static const u32 pio_t1min[] = { 70, 50, 30, 30, 25 }; -/* DIOR/DIOW to end cycle */ -static const u32 pio_t2min[] = { 165, 125, 100, 80, 70 }; -/* DIOR/DIOW asserted pulse width */ -static const u32 pio_teocmin[] = { 165, 125, 100, 70, 25 }; -/* DIOW data hold */ -static const u32 pio_t4min[] = { 30, 20, 15, 10, 10 }; - -/* ****************************************************************** - * Multiword DMA timing table - * ****************************************************************** - */ -/* mode: 0 1 2 */ -/* Cycle Time */ -static const u32 mdma_t0min[] = { 480, 150, 120 }; -/* DIOR/DIOW asserted pulse width */ -static const u32 mdma_tdmin[] = { 215, 80, 70 }; -/* DMACK to read data released */ -static const u32 mdma_thmin[] = { 20, 15, 10 }; -/* DIOR/DIOW to DMACK hold */ -static const u32 mdma_tjmin[] = { 20, 5, 5 }; -/* DIOR negated pulse width */ -static const u32 mdma_tkrmin[] = { 50, 50, 25 }; -/* DIOR negated pulse width */ -static const u32 mdma_tkwmin[] = { 215, 50, 25 }; -/* CS[1:0] valid to DIOR/DIOW */ -static const u32 mdma_tmmin[] = { 50, 30, 25 }; -/* DMACK to read data released */ -static const u32 mdma_tzmax[] = { 20, 25, 25 }; - -/** - * Ultra DMA timing table - */ -/* mode: 0 1 2 3 4 5 */ -static const u32 udma_tcycmin[] = { 112, 73, 54, 39, 25, 17 }; -static const u32 udma_tdvsmin[] = { 70, 48, 31, 20, 7, 5 }; -static const u32 udma_tenvmax[] = { 70, 70, 70, 55, 55, 50 }; -static const u32 udma_trpmin[] = { 160, 125, 100, 100, 100, 85 }; -static const u32 udma_tmin[] = { 5, 5, 5, 5, 3, 3 }; - - -static const u32 udma_tmlimin = 20; -static const u32 udma_tzahmin = 20; -static const u32 udma_tenvmin = 20; -static const u32 udma_tackmin = 20; -static const u32 udma_tssmin = 50; - -static void msleep(int count) -{ - int i; - - for (i = 0; i < count; i++) - udelay(1000); -} - -/** - * - * Function: num_clocks_min - * - * Description: - * calculate number of SCLK cycles to meet minimum timing - */ -static unsigned short num_clocks_min(unsigned long tmin, - unsigned long fsclk) -{ - unsigned long tmp ; - unsigned short result; - - tmp = tmin * (fsclk/1000/1000) / 1000; - result = (unsigned short)tmp; - if ((tmp*1000*1000) < (tmin*(fsclk/1000))) - result++; - - return result; -} - -/** - * bfin_set_piomode - Initialize host controller PATA PIO timings - * @ap: Port whose timings we are configuring - * @pio_mode: mode - * - * Set PIO mode for device. - * - * LOCKING: - * None (inherited from caller). - */ - -static void bfin_set_piomode(struct ata_port *ap, int pio_mode) -{ - int mode = pio_mode - XFER_PIO_0; - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - unsigned int fsclk = get_sclk(); - unsigned short teoc_reg, t2_reg, teoc_pio; - unsigned short t4_reg, t2_pio, t1_reg; - unsigned short n0, n6, t6min = 5; - - /* the most restrictive timing value is t6 and tc, the DIOW - data hold - * If one SCLK pulse is longer than this minimum value then register - * transfers cannot be supported at this frequency. - */ - n6 = num_clocks_min(t6min, fsclk); - if (mode >= 0 && mode <= 4 && n6 >= 1) { - debug("set piomode: mode=%d, fsclk=%ud\n", mode, fsclk); - /* calculate the timing values for register transfers. */ - while (mode > 0 && pio_fsclk[mode] > fsclk) - mode--; - - /* DIOR/DIOW to end cycle time */ - t2_reg = num_clocks_min(reg_t2min[mode], fsclk); - /* DIOR/DIOW asserted pulse width */ - teoc_reg = num_clocks_min(reg_teocmin[mode], fsclk); - /* Cycle Time */ - n0 = num_clocks_min(reg_t0min[mode], fsclk); - - /* increase t2 until we meed the minimum cycle length */ - if (t2_reg + teoc_reg < n0) - t2_reg = n0 - teoc_reg; - - /* calculate the timing values for pio transfers. */ - - /* DIOR/DIOW to end cycle time */ - t2_pio = num_clocks_min(pio_t2min[mode], fsclk); - /* DIOR/DIOW asserted pulse width */ - teoc_pio = num_clocks_min(pio_teocmin[mode], fsclk); - /* Cycle Time */ - n0 = num_clocks_min(pio_t0min[mode], fsclk); - - /* increase t2 until we meed the minimum cycle length */ - if (t2_pio + teoc_pio < n0) - t2_pio = n0 - teoc_pio; - - /* Address valid to DIOR/DIORW */ - t1_reg = num_clocks_min(pio_t1min[mode], fsclk); - - /* DIOW data hold */ - t4_reg = num_clocks_min(pio_t4min[mode], fsclk); - - ATAPI_SET_REG_TIM_0(base, (teoc_reg<<8 | t2_reg)); - ATAPI_SET_PIO_TIM_0(base, (t4_reg<<12 | t2_pio<<4 | t1_reg)); - ATAPI_SET_PIO_TIM_1(base, teoc_pio); - if (mode > 2) { - ATAPI_SET_CONTROL(base, - ATAPI_GET_CONTROL(base) | IORDY_EN); - } else { - ATAPI_SET_CONTROL(base, - ATAPI_GET_CONTROL(base) & ~IORDY_EN); - } - - /* Disable host ATAPI PIO interrupts */ - ATAPI_SET_INT_MASK(base, ATAPI_GET_INT_MASK(base) - & ~(PIO_DONE_MASK | HOST_TERM_XFER_MASK)); - SSYNC(); - } -} - -/** - * - * Function: wait_complete - * - * Description: Waits the interrupt from device - * - */ -static inline void wait_complete(void __iomem *base, unsigned short mask) -{ - unsigned short status; - unsigned int i = 0; - - for (i = 0; i < PATA_BFIN_WAIT_TIMEOUT; i++) { - status = ATAPI_GET_INT_STATUS(base) & mask; - if (status) - break; - } - - ATAPI_SET_INT_STATUS(base, mask); -} - -/** - * - * Function: write_atapi_register - * - * Description: Writes to ATA Device Resgister - * - */ - -static void write_atapi_register(void __iomem *base, - unsigned long ata_reg, unsigned short value) -{ - /* Program the ATA_DEV_TXBUF register with write data (to be - * written into the device). - */ - ATAPI_SET_DEV_TXBUF(base, value); - - /* Program the ATA_DEV_ADDR register with address of the - * device register (0x01 to 0x0F). - */ - ATAPI_SET_DEV_ADDR(base, ata_reg); - - /* Program the ATA_CTRL register with dir set to write (1) - */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | XFER_DIR)); - - /* ensure PIO DMA is not set */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA)); - - /* and start the transfer */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START)); - - /* Wait for the interrupt to indicate the end of the transfer. - * (We need to wait on and clear rhe ATA_DEV_INT interrupt status) - */ - wait_complete(base, PIO_DONE_INT); -} - -/** - * - * Function: read_atapi_register - * - *Description: Reads from ATA Device Resgister - * - */ - -static unsigned short read_atapi_register(void __iomem *base, - unsigned long ata_reg) -{ - /* Program the ATA_DEV_ADDR register with address of the - * device register (0x01 to 0x0F). - */ - ATAPI_SET_DEV_ADDR(base, ata_reg); - - /* Program the ATA_CTRL register with dir set to read (0) and - */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~XFER_DIR)); - - /* ensure PIO DMA is not set */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA)); - - /* and start the transfer */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START)); - - /* Wait for the interrupt to indicate the end of the transfer. - * (PIO_DONE interrupt is set and it doesn't seem to matter - * that we don't clear it) - */ - wait_complete(base, PIO_DONE_INT); - - /* Read the ATA_DEV_RXBUF register with write data (to be - * written into the device). - */ - return ATAPI_GET_DEV_RXBUF(base); -} - -/** - * - * Function: write_atapi_register_data - * - * Description: Writes to ATA Device Resgister - * - */ - -static void write_atapi_data(void __iomem *base, - int len, unsigned short *buf) -{ - int i; - - /* Set transfer length to 1 */ - ATAPI_SET_XFER_LEN(base, 1); - - /* Program the ATA_DEV_ADDR register with address of the - * ATA_REG_DATA - */ - ATAPI_SET_DEV_ADDR(base, ATA_REG_DATA); - - /* Program the ATA_CTRL register with dir set to write (1) - */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | XFER_DIR)); - - /* ensure PIO DMA is not set */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA)); - - for (i = 0; i < len; i++) { - /* Program the ATA_DEV_TXBUF register with write data (to be - * written into the device). - */ - ATAPI_SET_DEV_TXBUF(base, buf[i]); - - /* and start the transfer */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START)); - - /* Wait for the interrupt to indicate the end of the transfer. - * (We need to wait on and clear rhe ATA_DEV_INT - * interrupt status) - */ - wait_complete(base, PIO_DONE_INT); - } -} - -/** - * - * Function: read_atapi_register_data - * - * Description: Reads from ATA Device Resgister - * - */ - -static void read_atapi_data(void __iomem *base, - int len, unsigned short *buf) -{ - int i; - - /* Set transfer length to 1 */ - ATAPI_SET_XFER_LEN(base, 1); - - /* Program the ATA_DEV_ADDR register with address of the - * ATA_REG_DATA - */ - ATAPI_SET_DEV_ADDR(base, ATA_REG_DATA); - - /* Program the ATA_CTRL register with dir set to read (0) and - */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~XFER_DIR)); - - /* ensure PIO DMA is not set */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA)); - - for (i = 0; i < len; i++) { - /* and start the transfer */ - ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START)); - - /* Wait for the interrupt to indicate the end of the transfer. - * (PIO_DONE interrupt is set and it doesn't seem to matter - * that we don't clear it) - */ - wait_complete(base, PIO_DONE_INT); - - /* Read the ATA_DEV_RXBUF register with write data (to be - * written into the device). - */ - buf[i] = ATAPI_GET_DEV_RXBUF(base); - } -} - -/** - * bfin_check_status - Read device status reg & clear interrupt - * @ap: port where the device is - * - * Note: Original code is ata_check_status(). - */ - -static u8 bfin_check_status(struct ata_port *ap) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - return read_atapi_register(base, ATA_REG_STATUS); -} - -/** - * bfin_check_altstatus - Read device alternate status reg - * @ap: port where the device is - */ - -static u8 bfin_check_altstatus(struct ata_port *ap) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - return read_atapi_register(base, ATA_REG_ALTSTATUS); -} - -/** - * bfin_ata_busy_wait - Wait for a port status register - * @ap: Port to wait for. - * @bits: bits that must be clear - * @max: number of 10uS waits to perform - * - * Waits up to max*10 microseconds for the selected bits in the port's - * status register to be cleared. - * Returns final value of status register. - * - * LOCKING: - * Inherited from caller. - */ -static inline u8 bfin_ata_busy_wait(struct ata_port *ap, unsigned int bits, - unsigned int max, u8 usealtstatus) -{ - u8 status; - - do { - udelay(10); - if (usealtstatus) - status = bfin_check_altstatus(ap); - else - status = bfin_check_status(ap); - max--; - } while (status != 0xff && (status & bits) && (max > 0)); - - return status; -} - -/** - * bfin_ata_busy_sleep - sleep until BSY clears, or timeout - * @ap: port containing status register to be polled - * @tmout_pat: impatience timeout in msecs - * @tmout: overall timeout in msecs - * - * Sleep until ATA Status register bit BSY clears, - * or a timeout occurs. - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -static int bfin_ata_busy_sleep(struct ata_port *ap, - long tmout_pat, unsigned long tmout) -{ - u8 status; - - status = bfin_ata_busy_wait(ap, ATA_BUSY, 300, 0); - while (status != 0xff && (status & ATA_BUSY) && tmout_pat > 0) { - msleep(50); - tmout_pat -= 50; - status = bfin_ata_busy_wait(ap, ATA_BUSY, 3, 0); - } - - if (status != 0xff && (status & ATA_BUSY)) - printf("port is slow to respond, please be patient " - "(Status 0x%x)\n", status); - - while (status != 0xff && (status & ATA_BUSY) && tmout_pat > 0) { - msleep(50); - tmout_pat -= 50; - status = bfin_check_status(ap); - } - - if (status == 0xff) - return -ENODEV; - - if (status & ATA_BUSY) { - printf("port failed to respond " - "(%lu secs, Status 0x%x)\n", - DIV_ROUND_UP(tmout, 1000), status); - return -EBUSY; - } - - return 0; -} - -/** - * bfin_dev_select - Select device 0/1 on ATA bus - * @ap: ATA channel to manipulate - * @device: ATA device (numbered from zero) to select - * - * Note: Original code is ata_sff_dev_select(). - */ - -static void bfin_dev_select(struct ata_port *ap, unsigned int device) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - u8 tmp; - - - if (device == 0) - tmp = ATA_DEVICE_OBS; - else - tmp = ATA_DEVICE_OBS | ATA_DEV1; - - write_atapi_register(base, ATA_REG_DEVICE, tmp); - udelay(1); -} - -/** - * bfin_devchk - PATA device presence detection - * @ap: ATA channel to examine - * @device: Device to examine (starting at zero) - * - * Note: Original code is ata_devchk(). - */ - -static unsigned int bfin_devchk(struct ata_port *ap, - unsigned int device) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - u8 nsect, lbal; - - bfin_dev_select(ap, device); - - write_atapi_register(base, ATA_REG_NSECT, 0x55); - write_atapi_register(base, ATA_REG_LBAL, 0xaa); - - write_atapi_register(base, ATA_REG_NSECT, 0xaa); - write_atapi_register(base, ATA_REG_LBAL, 0x55); - - write_atapi_register(base, ATA_REG_NSECT, 0x55); - write_atapi_register(base, ATA_REG_LBAL, 0xaa); - - nsect = read_atapi_register(base, ATA_REG_NSECT); - lbal = read_atapi_register(base, ATA_REG_LBAL); - - if ((nsect == 0x55) && (lbal == 0xaa)) - return 1; /* we found a device */ - - return 0; /* nothing found */ -} - -/** - * bfin_bus_post_reset - PATA device post reset - * - * Note: Original code is ata_bus_post_reset(). - */ - -static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - unsigned int dev0 = devmask & (1 << 0); - unsigned int dev1 = devmask & (1 << 1); - long deadline; - - /* if device 0 was found in ata_devchk, wait for its - * BSY bit to clear - */ - if (dev0) - bfin_ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); - - /* if device 1 was found in ata_devchk, wait for - * register access, then wait for BSY to clear - */ - deadline = ATA_TMOUT_BOOT; - while (dev1) { - u8 nsect, lbal; - - bfin_dev_select(ap, 1); - nsect = read_atapi_register(base, ATA_REG_NSECT); - lbal = read_atapi_register(base, ATA_REG_LBAL); - if ((nsect == 1) && (lbal == 1)) - break; - if (deadline <= 0) { - dev1 = 0; - break; - } - msleep(50); /* give drive a breather */ - deadline -= 50; - } - if (dev1) - bfin_ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); - - /* is all this really necessary? */ - bfin_dev_select(ap, 0); - if (dev1) - bfin_dev_select(ap, 1); - if (dev0) - bfin_dev_select(ap, 0); -} - -/** - * bfin_bus_softreset - PATA device software reset - * - * Note: Original code is ata_bus_softreset(). - */ - -static unsigned int bfin_bus_softreset(struct ata_port *ap, - unsigned int devmask) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - - /* software reset. causes dev0 to be selected */ - write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg); - udelay(20); - write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg | ATA_SRST); - udelay(20); - write_atapi_register(base, ATA_REG_CTRL, ap->ctl_reg); - - /* spec mandates ">= 2ms" before checking status. - * We wait 150ms, because that was the magic delay used for - * ATAPI devices in Hale Landis's ATADRVR, for the period of time - * between when the ATA command register is written, and then - * status is checked. Because waiting for "a while" before - * checking status is fine, post SRST, we perform this magic - * delay here as well. - * - * Old drivers/ide uses the 2mS rule and then waits for ready - */ - msleep(150); - - /* Before we perform post reset processing we want to see if - * the bus shows 0xFF because the odd clown forgets the D7 - * pulldown resistor. - */ - if (bfin_check_status(ap) == 0xFF) - return 0; - - bfin_bus_post_reset(ap, devmask); - - return 0; -} - -/** - * bfin_softreset - reset host port via ATA SRST - * @ap: port to reset - * - * Note: Original code is ata_sff_softreset(). - */ - -static int bfin_softreset(struct ata_port *ap) -{ - unsigned int err_mask; - - ap->dev_mask = 0; - - /* determine if device 0/1 are present. - * only one device is supported on one port by now. - */ - if (bfin_devchk(ap, 0)) - ap->dev_mask |= (1 << 0); - else if (bfin_devchk(ap, 1)) - ap->dev_mask |= (1 << 1); - else - return -ENODEV; - - /* select device 0 again */ - bfin_dev_select(ap, 0); - - /* issue bus reset */ - err_mask = bfin_bus_softreset(ap, ap->dev_mask); - if (err_mask) { - printf("SRST failed (err_mask=0x%x)\n", - err_mask); - ap->dev_mask = 0; - return -EIO; - } - - return 0; -} - -/** - * bfin_irq_clear - Clear ATAPI interrupt. - * @ap: Port associated with this ATA transaction. - * - * Note: Original code is ata_sff_irq_clear(). - */ - -static void bfin_irq_clear(struct ata_port *ap) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - - ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT - | MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT - | MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT); -} - -static u8 bfin_wait_for_irq(struct ata_port *ap, unsigned int max) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - - do { - if (ATAPI_GET_INT_STATUS(base) & (ATAPI_DEV_INT - | MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT - | MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT)) { - break; - } - udelay(1000); - max--; - } while ((max > 0)); - - return max == 0; -} - -/** - * bfin_ata_reset_port - initialize BFIN ATAPI port. - */ - -static int bfin_ata_reset_port(struct ata_port *ap) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - int count; - unsigned short status; - - /* Disable all ATAPI interrupts */ - ATAPI_SET_INT_MASK(base, 0); - SSYNC(); - - /* Assert the RESET signal 25us*/ - ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | DEV_RST); - udelay(30); - - /* Negate the RESET signal for 2ms*/ - ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) & ~DEV_RST); - msleep(2); - - /* Wait on Busy flag to clear */ - count = 10000000; - do { - status = read_atapi_register(base, ATA_REG_STATUS); - } while (--count && (status & ATA_BUSY)); - - /* Enable only ATAPI Device interrupt */ - ATAPI_SET_INT_MASK(base, 1); - SSYNC(); - - return !count; -} - -/** - * - * Function: bfin_config_atapi_gpio - * - * Description: Configures the ATAPI pins for use - * - */ -static int bfin_config_atapi_gpio(struct ata_port *ap) -{ - const unsigned short pins[] = { - P_ATAPI_RESET, P_ATAPI_DIOR, P_ATAPI_DIOW, P_ATAPI_CS0, - P_ATAPI_CS1, P_ATAPI_DMACK, P_ATAPI_DMARQ, P_ATAPI_INTRQ, - P_ATAPI_IORDY, P_ATAPI_D0A, P_ATAPI_D1A, P_ATAPI_D2A, - P_ATAPI_D3A, P_ATAPI_D4A, P_ATAPI_D5A, P_ATAPI_D6A, - P_ATAPI_D7A, P_ATAPI_D8A, P_ATAPI_D9A, P_ATAPI_D10A, - P_ATAPI_D11A, P_ATAPI_D12A, P_ATAPI_D13A, P_ATAPI_D14A, - P_ATAPI_D15A, P_ATAPI_A0A, P_ATAPI_A1A, P_ATAPI_A2A, 0, - }; - - peripheral_request_list(pins, "pata_bfin"); - - return 0; -} - -/** - * bfin_atapi_probe - attach a bfin atapi interface - * @pdev: platform device - * - * Register a bfin atapi interface. - * - * - * Platform devices are expected to contain 2 resources per port: - * - * - I/O Base (IORESOURCE_IO) - * - IRQ (IORESOURCE_IRQ) - * - */ -static int bfin_ata_probe_port(struct ata_port *ap) -{ - if (bfin_config_atapi_gpio(ap)) { - printf("Requesting Peripherals faild\n"); - return -EFAULT; - } - - if (bfin_ata_reset_port(ap)) { - printf("Fail to reset ATAPI device\n"); - return -EFAULT; - } - - if (ap->ata_mode >= XFER_PIO_0 && ap->ata_mode <= XFER_PIO_4) - bfin_set_piomode(ap, ap->ata_mode); - else { - printf("Given ATA data transfer mode is not supported.\n"); - return -EFAULT; - } - - return 0; -} - -#define ATA_SECTOR_WORDS (ATA_SECT_SIZE/2) - -static void bfin_ata_identify(struct ata_port *ap, int dev) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - u8 status = 0; - static u16 iobuf[ATA_SECTOR_WORDS]; - u64 n_sectors = 0; - hd_driveid_t *iop = (hd_driveid_t *)iobuf; - - memset(iobuf, 0, sizeof(iobuf)); - - if (!(ap->dev_mask & (1 << dev))) - return; - - debug("port=%d dev=%d\n", ap->port_no, dev); - - bfin_dev_select(ap, dev); - - status = 0; - /* Device Identify Command */ - write_atapi_register(base, ATA_REG_CMD, ATA_CMD_ID_ATA); - bfin_check_altstatus(ap); - udelay(10); - - status = bfin_ata_busy_wait(ap, ATA_BUSY, 1000, 0); - if (status & ATA_ERR) { - printf("\ndevice not responding\n"); - ap->dev_mask &= ~(1 << dev); - return; - } - - read_atapi_data(base, ATA_SECTOR_WORDS, iobuf); - - ata_swap_buf_le16(iobuf, ATA_SECTOR_WORDS); - - /* we require LBA and DMA support (bits 8 & 9 of word 49) */ - if (!ata_id_has_dma(iobuf) || !ata_id_has_lba(iobuf)) - printf("ata%u: no dma/lba\n", ap->port_no); - -#ifdef DEBUG - ata_dump_id(iobuf); -#endif - - n_sectors = ata_id_n_sectors(iobuf); - - if (n_sectors == 0) { - ap->dev_mask &= ~(1 << dev); - return; - } - - ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].revision, - ATA_ID_FW_REV, sizeof(sata_dev_desc[ap->port_no].revision)); - ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].vendor, - ATA_ID_PROD, sizeof(sata_dev_desc[ap->port_no].vendor)); - ata_id_c_string(iobuf, (unsigned char *)sata_dev_desc[ap->port_no].product, - ATA_ID_SERNO, sizeof(sata_dev_desc[ap->port_no].product)); - - if ((iop->config & 0x0080) == 0x0080) - sata_dev_desc[ap->port_no].removable = 1; - else - sata_dev_desc[ap->port_no].removable = 0; - - sata_dev_desc[ap->port_no].lba = (u32) n_sectors; - debug("lba=0x%lx\n", sata_dev_desc[ap->port_no].lba); - -#ifdef CONFIG_LBA48 - if (iop->command_set_2 & 0x0400) - sata_dev_desc[ap->port_no].lba48 = 1; - else - sata_dev_desc[ap->port_no].lba48 = 0; -#endif - - /* assuming HD */ - sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK; - sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE; - sata_dev_desc[ap->port_no].log2blksz = - LOG2(sata_dev_desc[ap->port_no].blksz); - sata_dev_desc[ap->port_no].lun = 0; /* just to fill something in... */ - - printf("PATA device#%d %s is found on ata port#%d.\n", - ap->port_no%PATA_DEV_NUM_PER_PORT, - sata_dev_desc[ap->port_no].vendor, - ap->port_no/PATA_DEV_NUM_PER_PORT); -} - -static void bfin_ata_set_Feature_cmd(struct ata_port *ap, int dev) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - u8 status = 0; - - if (!(ap->dev_mask & (1 << dev))) - return; - - bfin_dev_select(ap, dev); - - write_atapi_register(base, ATA_REG_FEATURE, SETFEATURES_XFER); - write_atapi_register(base, ATA_REG_NSECT, ap->ata_mode); - write_atapi_register(base, ATA_REG_LBAL, 0); - write_atapi_register(base, ATA_REG_LBAM, 0); - write_atapi_register(base, ATA_REG_LBAH, 0); - - write_atapi_register(base, ATA_REG_DEVICE, ATA_DEVICE_OBS); - write_atapi_register(base, ATA_REG_CMD, ATA_CMD_SET_FEATURES); - - udelay(50); - msleep(150); - - status = bfin_ata_busy_wait(ap, ATA_BUSY, 5000, 0); - if ((status & (ATA_BUSY | ATA_ERR))) { - printf("Error : status 0x%02x\n", status); - ap->dev_mask &= ~(1 << dev); - } -} - -int scan_sata(int dev) -{ - /* dev is the index of each ata device in the system. one PATA port - * contains 2 devices. one element in scan_done array indicates one - * PATA port. device connected to one PATA port is selected by - * bfin_dev_select() before access. - */ - struct ata_port *ap = &port[dev]; - static int scan_done[(CONFIG_SYS_SATA_MAX_DEVICE+1)/PATA_DEV_NUM_PER_PORT]; - - if (scan_done[dev/PATA_DEV_NUM_PER_PORT]) - return 0; - - /* Check for attached device */ - if (!bfin_ata_probe_port(ap)) { - if (bfin_softreset(ap)) { - /* soft reset failed, try a hard one */ - bfin_ata_reset_port(ap); - if (bfin_softreset(ap)) - scan_done[dev/PATA_DEV_NUM_PER_PORT] = 1; - } else { - scan_done[dev/PATA_DEV_NUM_PER_PORT] = 1; - } - } - if (scan_done[dev/PATA_DEV_NUM_PER_PORT]) { - /* Probe device and set xfer mode */ - bfin_ata_identify(ap, dev%PATA_DEV_NUM_PER_PORT); - bfin_ata_set_Feature_cmd(ap, dev%PATA_DEV_NUM_PER_PORT); - part_init(&sata_dev_desc[dev]); - return 0; - } - - printf("PATA device#%d is not present on ATA port#%d.\n", - ap->port_no%PATA_DEV_NUM_PER_PORT, - ap->port_no/PATA_DEV_NUM_PER_PORT); - - return -1; -} - -int init_sata(int dev) -{ - struct ata_port *ap = &port[dev]; - static u8 init_done; - int res = 1; - - if (init_done) - return res; - - init_done = 1; - - switch (dev/PATA_DEV_NUM_PER_PORT) { - case 0: - ap->ioaddr.ctl_addr = ATAPI_CONTROL; - ap->ata_mode = CONFIG_BFIN_ATA_MODE; - break; - default: - printf("Tried to scan unknown port %d.\n", dev); - return res; - } - - if (ap->ata_mode < XFER_PIO_0 || ap->ata_mode > XFER_PIO_4) { - ap->ata_mode = XFER_PIO_4; - printf("DMA mode is not supported. Set to PIO mode 4.\n"); - } - - ap->port_no = dev; - ap->ctl_reg = 0x8; /*Default value of control reg */ - - res = 0; - return res; -} - -int reset_sata(int dev) -{ - return 0; -} - -/* Read up to 255 sectors - * - * Returns sectors read -*/ -static u8 do_one_read(struct ata_port *ap, u64 blknr, u8 blkcnt, u16 *buffer, - uchar lba48) -{ - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - u8 sr = 0; - u8 status; - u16 err = 0; - - if (!(bfin_check_status(ap) & ATA_DRDY)) { - printf("Device ata%d not ready\n", ap->port_no); - return 0; - } - - /* Set up transfer */ -#ifdef CONFIG_LBA48 - if (lba48) { - /* write high bits */ - write_atapi_register(base, ATA_REG_NSECT, 0); - write_atapi_register(base, ATA_REG_LBAL, (blknr >> 24) & 0xFF); - write_atapi_register(base, ATA_REG_LBAM, (blknr >> 32) & 0xFF); - write_atapi_register(base, ATA_REG_LBAH, (blknr >> 40) & 0xFF); - } -#endif - write_atapi_register(base, ATA_REG_NSECT, blkcnt); - write_atapi_register(base, ATA_REG_LBAL, (blknr >> 0) & 0xFF); - write_atapi_register(base, ATA_REG_LBAM, (blknr >> 8) & 0xFF); - write_atapi_register(base, ATA_REG_LBAH, (blknr >> 16) & 0xFF); - -#ifdef CONFIG_LBA48 - if (lba48) { - write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA); - write_atapi_register(base, ATA_REG_CMD, ATA_CMD_PIO_READ_EXT); - } else -#endif - { - write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA | ((blknr >> 24) & 0xF)); - write_atapi_register(base, ATA_REG_CMD, ATA_CMD_PIO_READ); - } - status = bfin_ata_busy_wait(ap, ATA_BUSY, 500000, 1); - - if (status & (ATA_BUSY | ATA_ERR)) { - printf("Device %d not responding status 0x%x.\n", ap->port_no, status); - err = read_atapi_register(base, ATA_REG_ERR); - printf("Error reg = 0x%x\n", err); - return sr; - } - - while (blkcnt--) { - if (bfin_wait_for_irq(ap, 500)) { - printf("ata%u irq failed\n", ap->port_no); - return sr; - } - - status = bfin_check_status(ap); - if (status & ATA_ERR) { - err = read_atapi_register(base, ATA_REG_ERR); - printf("ata%u error %d\n", ap->port_no, err); - return sr; - } - bfin_irq_clear(ap); - - /* Read one sector */ - read_atapi_data(base, ATA_SECTOR_WORDS, buffer); - buffer += ATA_SECTOR_WORDS; - sr++; - } - - return sr; -} - -ulong sata_read(int dev, ulong block, lbaint_t blkcnt, void *buff) -{ - struct ata_port *ap = &port[dev]; - ulong n = 0, sread; - u16 *buffer = (u16 *) buff; - u8 status = 0; - u64 blknr = (u64) block; - unsigned char lba48 = 0; - -#ifdef CONFIG_LBA48 - if (blknr > 0xfffffff) { - if (!sata_dev_desc[dev].lba48) { - printf("Drive doesn't support 48-bit addressing\n"); - return 0; - } - /* more than 28 bits used, use 48bit mode */ - lba48 = 1; - } -#endif - bfin_dev_select(ap, dev%PATA_DEV_NUM_PER_PORT); - - while (blkcnt > 0) { - - if (blkcnt > 255) - sread = 255; - else - sread = blkcnt; - - status = do_one_read(ap, blknr, sread, buffer, lba48); - if (status != sread) { - printf("Read failed\n"); - return n; - } - - blkcnt -= sread; - blknr += sread; - n += sread; - buffer += sread * ATA_SECTOR_WORDS; - } - return n; -} - -ulong sata_write(int dev, ulong block, lbaint_t blkcnt, const void *buff) -{ - struct ata_port *ap = &port[dev]; - void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; - ulong n = 0; - u16 *buffer = (u16 *) buff; - unsigned char status = 0; - u64 blknr = (u64) block; -#ifdef CONFIG_LBA48 - unsigned char lba48 = 0; - - if (blknr > 0xfffffff) { - if (!sata_dev_desc[dev].lba48) { - printf("Drive doesn't support 48-bit addressing\n"); - return 0; - } - /* more than 28 bits used, use 48bit mode */ - lba48 = 1; - } -#endif - - bfin_dev_select(ap, dev%PATA_DEV_NUM_PER_PORT); - - while (blkcnt-- > 0) { - status = bfin_ata_busy_wait(ap, ATA_BUSY, 50000, 0); - if (status & ATA_BUSY) { - printf("ata%u failed to respond\n", ap->port_no); - return n; - } -#ifdef CONFIG_LBA48 - if (lba48) { - /* write high bits */ - write_atapi_register(base, ATA_REG_NSECT, 0); - write_atapi_register(base, ATA_REG_LBAL, - (blknr >> 24) & 0xFF); - write_atapi_register(base, ATA_REG_LBAM, - (blknr >> 32) & 0xFF); - write_atapi_register(base, ATA_REG_LBAH, - (blknr >> 40) & 0xFF); - } -#endif - write_atapi_register(base, ATA_REG_NSECT, 1); - write_atapi_register(base, ATA_REG_LBAL, (blknr >> 0) & 0xFF); - write_atapi_register(base, ATA_REG_LBAM, (blknr >> 8) & 0xFF); - write_atapi_register(base, ATA_REG_LBAH, (blknr >> 16) & 0xFF); -#ifdef CONFIG_LBA48 - if (lba48) { - write_atapi_register(base, ATA_REG_DEVICE, ATA_LBA); - write_atapi_register(base, ATA_REG_CMD, - ATA_CMD_PIO_WRITE_EXT); - } else -#endif - { - write_atapi_register(base, ATA_REG_DEVICE, - ATA_LBA | ((blknr >> 24) & 0xF)); - write_atapi_register(base, ATA_REG_CMD, - ATA_CMD_PIO_WRITE); - } - - /*may take up to 5 sec */ - status = bfin_ata_busy_wait(ap, ATA_BUSY, 50000, 0); - if ((status & (ATA_DRQ | ATA_BUSY | ATA_ERR)) != ATA_DRQ) { - printf("Error no DRQ dev %d blk %ld: sts 0x%02x\n", - ap->port_no, (ulong) blknr, status); - return n; - } - - write_atapi_data(base, ATA_SECTOR_WORDS, buffer); - bfin_check_altstatus(ap); - udelay(1); - - ++n; - ++blknr; - buffer += ATA_SECTOR_WORDS; - } - return n; -} diff --git a/drivers/block/pata_bfin.h b/drivers/block/pata_bfin.h deleted file mode 100644 index b678f60b2d7..00000000000 --- a/drivers/block/pata_bfin.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Driver for Blackfin on-chip ATAPI controller. - * - * Enter bugs at http://blackfin.uclinux.org/ - * - * Copyright (c) 2008 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef PATA_BFIN_H -#define PATA_BFIN_H - -#include - -struct ata_ioports { - unsigned long cmd_addr; - unsigned long data_addr; - unsigned long error_addr; - unsigned long feature_addr; - unsigned long nsect_addr; - unsigned long lbal_addr; - unsigned long lbam_addr; - unsigned long lbah_addr; - unsigned long device_addr; - unsigned long status_addr; - unsigned long command_addr; - unsigned long altstatus_addr; - unsigned long ctl_addr; - unsigned long bmdma_addr; - unsigned long scr_addr; -}; - -struct ata_port { - unsigned int port_no; /* primary=0, secondary=1 */ - struct ata_ioports ioaddr; /* ATA cmd/ctl/dma reg blks */ - unsigned long flag; - unsigned int ata_mode; - unsigned char ctl_reg; - unsigned char last_ctl; - unsigned char dev_mask; -}; - -#define DRV_NAME "pata-bfin" -#define DRV_VERSION "0.9" - -#define ATA_REG_CTRL 0x0E -#define ATA_REG_ALTSTATUS ATA_REG_CTRL -#define ATA_TMOUT_BOOT 30000 -#define ATA_TMOUT_BOOT_QUICK 7000 - -#define PATA_BFIN_WAIT_TIMEOUT 10000 -#define PATA_DEV_NUM_PER_PORT 2 - -/* These are the offset of the controller's registers */ -#define ATAPI_OFFSET_CONTROL 0x00 -#define ATAPI_OFFSET_STATUS 0x04 -#define ATAPI_OFFSET_DEV_ADDR 0x08 -#define ATAPI_OFFSET_DEV_TXBUF 0x0c -#define ATAPI_OFFSET_DEV_RXBUF 0x10 -#define ATAPI_OFFSET_INT_MASK 0x14 -#define ATAPI_OFFSET_INT_STATUS 0x18 -#define ATAPI_OFFSET_XFER_LEN 0x1c -#define ATAPI_OFFSET_LINE_STATUS 0x20 -#define ATAPI_OFFSET_SM_STATE 0x24 -#define ATAPI_OFFSET_TERMINATE 0x28 -#define ATAPI_OFFSET_PIO_TFRCNT 0x2c -#define ATAPI_OFFSET_DMA_TFRCNT 0x30 -#define ATAPI_OFFSET_UMAIN_TFRCNT 0x34 -#define ATAPI_OFFSET_UDMAOUT_TFRCNT 0x38 -#define ATAPI_OFFSET_REG_TIM_0 0x40 -#define ATAPI_OFFSET_PIO_TIM_0 0x44 -#define ATAPI_OFFSET_PIO_TIM_1 0x48 -#define ATAPI_OFFSET_MULTI_TIM_0 0x50 -#define ATAPI_OFFSET_MULTI_TIM_1 0x54 -#define ATAPI_OFFSET_MULTI_TIM_2 0x58 -#define ATAPI_OFFSET_ULTRA_TIM_0 0x60 -#define ATAPI_OFFSET_ULTRA_TIM_1 0x64 -#define ATAPI_OFFSET_ULTRA_TIM_2 0x68 -#define ATAPI_OFFSET_ULTRA_TIM_3 0x6c - - -#define ATAPI_GET_CONTROL(base)\ - bfin_read16(base + ATAPI_OFFSET_CONTROL) -#define ATAPI_SET_CONTROL(base, val)\ - bfin_write16(base + ATAPI_OFFSET_CONTROL, val) -#define ATAPI_GET_STATUS(base)\ - bfin_read16(base + ATAPI_OFFSET_STATUS) -#define ATAPI_GET_DEV_ADDR(base)\ - bfin_read16(base + ATAPI_OFFSET_DEV_ADDR) -#define ATAPI_SET_DEV_ADDR(base, val)\ - bfin_write16(base + ATAPI_OFFSET_DEV_ADDR, val) -#define ATAPI_GET_DEV_TXBUF(base)\ - bfin_read16(base + ATAPI_OFFSET_DEV_TXBUF) -#define ATAPI_SET_DEV_TXBUF(base, val)\ - bfin_write16(base + ATAPI_OFFSET_DEV_TXBUF, val) -#define ATAPI_GET_DEV_RXBUF(base)\ - bfin_read16(base + ATAPI_OFFSET_DEV_RXBUF) -#define ATAPI_SET_DEV_RXBUF(base, val)\ - bfin_write16(base + ATAPI_OFFSET_DEV_RXBUF, val) -#define ATAPI_GET_INT_MASK(base)\ - bfin_read16(base + ATAPI_OFFSET_INT_MASK) -#define ATAPI_SET_INT_MASK(base, val)\ - bfin_write16(base + ATAPI_OFFSET_INT_MASK, val) -#define ATAPI_GET_INT_STATUS(base)\ - bfin_read16(base + ATAPI_OFFSET_INT_STATUS) -#define ATAPI_SET_INT_STATUS(base, val)\ - bfin_write16(base + ATAPI_OFFSET_INT_STATUS, val) -#define ATAPI_GET_XFER_LEN(base)\ - bfin_read16(base + ATAPI_OFFSET_XFER_LEN) -#define ATAPI_SET_XFER_LEN(base, val)\ - bfin_write16(base + ATAPI_OFFSET_XFER_LEN, val) -#define ATAPI_GET_LINE_STATUS(base)\ - bfin_read16(base + ATAPI_OFFSET_LINE_STATUS) -#define ATAPI_GET_SM_STATE(base)\ - bfin_read16(base + ATAPI_OFFSET_SM_STATE) -#define ATAPI_GET_TERMINATE(base)\ - bfin_read16(base + ATAPI_OFFSET_TERMINATE) -#define ATAPI_SET_TERMINATE(base, val)\ - bfin_write16(base + ATAPI_OFFSET_TERMINATE, val) -#define ATAPI_GET_PIO_TFRCNT(base)\ - bfin_read16(base + ATAPI_OFFSET_PIO_TFRCNT) -#define ATAPI_GET_DMA_TFRCNT(base)\ - bfin_read16(base + ATAPI_OFFSET_DMA_TFRCNT) -#define ATAPI_GET_UMAIN_TFRCNT(base)\ - bfin_read16(base + ATAPI_OFFSET_UMAIN_TFRCNT) -#define ATAPI_GET_UDMAOUT_TFRCNT(base)\ - bfin_read16(base + ATAPI_OFFSET_UDMAOUT_TFRCNT) -#define ATAPI_GET_REG_TIM_0(base)\ - bfin_read16(base + ATAPI_OFFSET_REG_TIM_0) -#define ATAPI_SET_REG_TIM_0(base, val)\ - bfin_write16(base + ATAPI_OFFSET_REG_TIM_0, val) -#define ATAPI_GET_PIO_TIM_0(base)\ - bfin_read16(base + ATAPI_OFFSET_PIO_TIM_0) -#define ATAPI_SET_PIO_TIM_0(base, val)\ - bfin_write16(base + ATAPI_OFFSET_PIO_TIM_0, val) -#define ATAPI_GET_PIO_TIM_1(base)\ - bfin_read16(base + ATAPI_OFFSET_PIO_TIM_1) -#define ATAPI_SET_PIO_TIM_1(base, val)\ - bfin_write16(base + ATAPI_OFFSET_PIO_TIM_1, val) -#define ATAPI_GET_MULTI_TIM_0(base)\ - bfin_read16(base + ATAPI_OFFSET_MULTI_TIM_0) -#define ATAPI_SET_MULTI_TIM_0(base, val)\ - bfin_write16(base + ATAPI_OFFSET_MULTI_TIM_0, val) -#define ATAPI_GET_MULTI_TIM_1(base)\ - bfin_read16(base + ATAPI_OFFSET_MULTI_TIM_1) -#define ATAPI_SET_MULTI_TIM_1(base, val)\ - bfin_write16(base + ATAPI_OFFSET_MULTI_TIM_1, val) -#define ATAPI_GET_MULTI_TIM_2(base)\ - bfin_read16(base + ATAPI_OFFSET_MULTI_TIM_2) -#define ATAPI_SET_MULTI_TIM_2(base, val)\ - bfin_write16(base + ATAPI_OFFSET_MULTI_TIM_2, val) -#define ATAPI_GET_ULTRA_TIM_0(base)\ - bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_0) -#define ATAPI_SET_ULTRA_TIM_0(base, val)\ - bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_0, val) -#define ATAPI_GET_ULTRA_TIM_1(base)\ - bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_1) -#define ATAPI_SET_ULTRA_TIM_1(base, val)\ - bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_1, val) -#define ATAPI_GET_ULTRA_TIM_2(base)\ - bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_2) -#define ATAPI_SET_ULTRA_TIM_2(base, val)\ - bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_2, val) -#define ATAPI_GET_ULTRA_TIM_3(base)\ - bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_3) -#define ATAPI_SET_ULTRA_TIM_3(base, val)\ - bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_3, val) - -#endif diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index a61a9e9ca6c..de91f1423bc 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -14,7 +14,6 @@ obj-$(CONFIG_GENERIC_MMC) += mmc_legacy.o endif obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o -obj-$(CONFIG_BFIN_SDH) += bfin_sdh.o obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o obj-$(CONFIG_MMC_DW) += dw_mmc.o diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c deleted file mode 100644 index 1627dca3a1d..00000000000 --- a/drivers/mmc/bfin_sdh.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Driver for Blackfin on-chip SDH controller - * - * Copyright (c) 2008-2009 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__ADSPBF50x__) || defined(__ADSPBF51x__) || defined(__ADSPBF60x__) -# define bfin_read_SDH_CLK_CTL bfin_read_RSI_CLK_CONTROL -# define bfin_write_SDH_CLK_CTL bfin_write_RSI_CLK_CONTROL -# define bfin_write_SDH_ARGUMENT bfin_write_RSI_ARGUMENT -# define bfin_write_SDH_COMMAND bfin_write_RSI_COMMAND -# define bfin_read_SDH_RESPONSE0 bfin_read_RSI_RESPONSE0 -# define bfin_read_SDH_RESPONSE1 bfin_read_RSI_RESPONSE1 -# define bfin_read_SDH_RESPONSE2 bfin_read_RSI_RESPONSE2 -# define bfin_read_SDH_RESPONSE3 bfin_read_RSI_RESPONSE3 -# define bfin_write_SDH_DATA_TIMER bfin_write_RSI_DATA_TIMER -# define bfin_write_SDH_DATA_LGTH bfin_write_RSI_DATA_LGTH -# define bfin_read_SDH_DATA_CTL bfin_read_RSI_DATA_CONTROL -# define bfin_write_SDH_DATA_CTL bfin_write_RSI_DATA_CONTROL -# define bfin_read_SDH_STATUS bfin_read_RSI_STATUS -# define bfin_write_SDH_STATUS_CLR bfin_write_RSI_STATUSCL -# define bfin_read_SDH_CFG bfin_read_RSI_CONFIG -# define bfin_write_SDH_CFG bfin_write_RSI_CONFIG -# if defined(__ADSPBF60x__) -# define bfin_read_SDH_BLK_SIZE bfin_read_RSI_BLKSZ -# define bfin_write_SDH_BLK_SIZE bfin_write_RSI_BLKSZ -# define bfin_write_DMA_START_ADDR bfin_write_DMA10_START_ADDR -# define bfin_write_DMA_X_COUNT bfin_write_DMA10_X_COUNT -# define bfin_write_DMA_X_MODIFY bfin_write_DMA10_X_MODIFY -# define bfin_write_DMA_CONFIG bfin_write_DMA10_CONFIG -# else -# define bfin_read_SDH_PWR_CTL bfin_read_RSI_PWR_CONTROL -# define bfin_write_SDH_PWR_CTL bfin_write_RSI_PWR_CONTROL -# define bfin_write_DMA_START_ADDR bfin_write_DMA4_START_ADDR -# define bfin_write_DMA_X_COUNT bfin_write_DMA4_X_COUNT -# define bfin_write_DMA_X_MODIFY bfin_write_DMA4_X_MODIFY -# define bfin_write_DMA_CONFIG bfin_write_DMA4_CONFIG -# endif -# define PORTMUX_PINS \ - { P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0 } -#elif defined(__ADSPBF54x__) -# define bfin_write_DMA_START_ADDR bfin_write_DMA22_START_ADDR -# define bfin_write_DMA_X_COUNT bfin_write_DMA22_X_COUNT -# define bfin_write_DMA_X_MODIFY bfin_write_DMA22_X_MODIFY -# define bfin_write_DMA_CONFIG bfin_write_DMA22_CONFIG -# define PORTMUX_PINS \ - { P_SD_D0, P_SD_D1, P_SD_D2, P_SD_D3, P_SD_CLK, P_SD_CMD, 0 } -#else -# error no support for this proc yet -#endif - -static int -sdh_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd) -{ - unsigned int status, timeout; - int cmd = mmc_cmd->cmdidx; - int flags = mmc_cmd->resp_type; - int arg = mmc_cmd->cmdarg; - int ret; - u16 sdh_cmd; - - sdh_cmd = cmd | CMD_E; - if (flags & MMC_RSP_PRESENT) - sdh_cmd |= CMD_RSP; - if (flags & MMC_RSP_136) - sdh_cmd |= CMD_L_RSP; -#ifdef RSI_BLKSZ - sdh_cmd |= CMD_DATA0_BUSY; -#endif - - bfin_write_SDH_ARGUMENT(arg); - bfin_write_SDH_COMMAND(sdh_cmd); - - /* wait for a while */ - timeout = 0; - do { - if (++timeout > 1000000) { - status = CMD_TIME_OUT; - break; - } - udelay(1); - status = bfin_read_SDH_STATUS(); - } while (!(status & (CMD_SENT | CMD_RESP_END | CMD_TIME_OUT | - CMD_CRC_FAIL))); - - if (flags & MMC_RSP_PRESENT) { - mmc_cmd->response[0] = bfin_read_SDH_RESPONSE0(); - if (flags & MMC_RSP_136) { - mmc_cmd->response[1] = bfin_read_SDH_RESPONSE1(); - mmc_cmd->response[2] = bfin_read_SDH_RESPONSE2(); - mmc_cmd->response[3] = bfin_read_SDH_RESPONSE3(); - } - } - - if (status & CMD_TIME_OUT) - ret = -ETIMEDOUT; - else if (status & CMD_CRC_FAIL && flags & MMC_RSP_CRC) - ret = -ECOMM; - else - ret = 0; - - bfin_write_SDH_STATUS_CLR(CMD_SENT_STAT | CMD_RESP_END_STAT | - CMD_TIMEOUT_STAT | CMD_CRC_FAIL_STAT); -#ifdef RSI_BLKSZ - /* wait till card ready */ - while (!(bfin_read_RSI_ESTAT() & SD_CARD_READY)) - continue; - bfin_write_RSI_ESTAT(SD_CARD_READY); -#endif - - return ret; -} - -/* set data for single block transfer */ -static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data) -{ - u16 data_ctl = 0; - u16 dma_cfg = 0; - unsigned long data_size = data->blocksize * data->blocks; - - /* Don't support write yet. */ - if (data->flags & MMC_DATA_WRITE) - return -EOPNOTSUPP; -#ifndef RSI_BLKSZ - data_ctl |= ((ffs(data->blocksize) - 1) << 4); -#else - bfin_write_SDH_BLK_SIZE(data->blocksize); -#endif - data_ctl |= DTX_DIR; - bfin_write_SDH_DATA_CTL(data_ctl); - dma_cfg = WDSIZE_32 | PSIZE_32 | RESTART | WNR | DMAEN; - - bfin_write_SDH_DATA_TIMER(-1); - - blackfin_dcache_flush_invalidate_range(data->dest, - data->dest + data_size); - /* configure DMA */ - bfin_write_DMA_START_ADDR(data->dest); - bfin_write_DMA_X_COUNT(data_size / 4); - bfin_write_DMA_X_MODIFY(4); - bfin_write_DMA_CONFIG(dma_cfg); - bfin_write_SDH_DATA_LGTH(data_size); - /* kick off transfer */ - bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E); - - return 0; -} - - -static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - u32 status; - int ret = 0; - - if (data) { - ret = sdh_setup_data(mmc, data); - if (ret) - return ret; - } - - ret = sdh_send_cmd(mmc, cmd); - if (ret) { - bfin_write_SDH_COMMAND(0); - bfin_write_DMA_CONFIG(0); - bfin_write_SDH_DATA_CTL(0); - SSYNC(); - printf("sending CMD%d failed\n", cmd->cmdidx); - return ret; - } - - if (data) { - do { - udelay(1); - status = bfin_read_SDH_STATUS(); - } while (!(status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | - RX_OVERRUN))); - - if (status & DAT_TIME_OUT) { - bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT); - ret = -ETIMEDOUT; - } else if (status & (DAT_CRC_FAIL | RX_OVERRUN)) { - bfin_write_SDH_STATUS_CLR(DAT_CRC_FAIL_STAT | RX_OVERRUN_STAT); - ret = -ECOMM; - } else - bfin_write_SDH_STATUS_CLR(DAT_BLK_END_STAT | DAT_END_STAT); - - if (ret) { - printf("tranfering data failed\n"); - return ret; - } - } - return 0; -} - -static void sdh_set_clk(unsigned long clk) -{ - unsigned long sys_clk; - unsigned long clk_div; - u16 clk_ctl = 0; - - clk_ctl = bfin_read_SDH_CLK_CTL(); - if (clk) { - /* setting SD_CLK */ - sys_clk = get_sclk(); - bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E); - if (sys_clk % (2 * clk) == 0) - clk_div = sys_clk / (2 * clk) - 1; - else - clk_div = sys_clk / (2 * clk); - - if (clk_div > 0xff) - clk_div = 0xff; - clk_ctl |= (clk_div & 0xff); - clk_ctl |= CLK_E; - bfin_write_SDH_CLK_CTL(clk_ctl); - } else - bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E); -} - -static int bfin_sdh_set_ios(struct mmc *mmc) -{ - u16 cfg = 0; - u16 clk_ctl = 0; - - if (mmc->bus_width == 4) { - cfg = bfin_read_SDH_CFG(); -#ifndef RSI_BLKSZ - cfg &= ~PD_SDDAT3; -#endif - cfg |= PUP_SDDAT3; - bfin_write_SDH_CFG(cfg); - clk_ctl |= WIDE_BUS_4; - } - bfin_write_SDH_CLK_CTL(clk_ctl); - sdh_set_clk(mmc->clock); - - return 0; -} - -static int bfin_sdh_init(struct mmc *mmc) -{ - const unsigned short pins[] = PORTMUX_PINS; - int ret; - - /* Initialize sdh controller */ - ret = peripheral_request_list(pins, "bfin_sdh"); - if (ret < 0) - return ret; -#if defined(__ADSPBF54x__) - bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1); -#endif - bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN); - /* Disable card detect pin */ - bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | 0x60); -#ifndef RSI_BLKSZ - bfin_write_SDH_PWR_CTL(PWR_ON | ROD_CTL); -#else - bfin_write_SDH_CFG(bfin_read_SDH_CFG() | PWR_ON); -#endif - return 0; -} - -static const struct mmc_ops bfin_mmc_ops = { - .send_cmd = bfin_sdh_request, - .set_ios = bfin_sdh_set_ios, - .init = bfin_sdh_init, -}; - -static struct mmc_config bfin_mmc_cfg = { - .name = "Blackfin SDH", - .ops = &bfin_mmc_ops, - .host_caps = MMC_MODE_4BIT, - .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, - .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, -}; - -int bfin_mmc_init(bd_t *bis) -{ - struct mmc *mmc; - - bfin_mmc_cfg.f_max = get_sclk(); - bfin_mmc_cfg.f_min = bfin_mmc_cfg.f_max >> 9; - - mmc = mmc_create(&bfin_mmc_cfg, NULL); - if (mmc == NULL) - return -1; - - return 0; -} diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index fd4bb66f50d..82358f674bd 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -42,7 +42,6 @@ obj-$(CONFIG_NAND_ECC_BCH) += nand_bch.o obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o obj-$(CONFIG_NAND_ARASAN) += arasan_nfc.o -obj-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o obj-$(CONFIG_NAND_DAVINCI) += davinci_nand.o obj-$(CONFIG_NAND_DENALI) += denali.o obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o diff --git a/drivers/mtd/nand/bfin_nand.c b/drivers/mtd/nand/bfin_nand.c deleted file mode 100644 index 7c11868cd31..00000000000 --- a/drivers/mtd/nand/bfin_nand.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Driver for Blackfin on-chip NAND controller. - * - * Enter bugs at http://blackfin.uclinux.org/ - * - * Copyright (c) 2007-2008 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -/* TODO: - * - move bit defines into mach-common/bits/nand.h - * - try and replace all IRQSTAT usage with STAT polling - * - have software ecc mode use same algo as hw ecc ? - */ - -#include -#include -#include - -#ifdef DEBUG -# define pr_stamp() printf("%s:%s:%i: here i am\n", __FILE__, __func__, __LINE__) -#else -# define pr_stamp() -#endif - -#include - -#include -#include - -/* Bit masks for NFC_CTL */ - -#define WR_DLY 0xf /* Write Strobe Delay */ -#define RD_DLY 0xf0 /* Read Strobe Delay */ -#define NWIDTH 0x100 /* NAND Data Width */ -#define PG_SIZE 0x200 /* Page Size */ - -/* Bit masks for NFC_STAT */ - -#define NBUSY 0x1 /* Not Busy */ -#define WB_FULL 0x2 /* Write Buffer Full */ -#define PG_WR_STAT 0x4 /* Page Write Pending */ -#define PG_RD_STAT 0x8 /* Page Read Pending */ -#define WB_EMPTY 0x10 /* Write Buffer Empty */ - -/* Bit masks for NFC_IRQSTAT */ - -#define NBUSYIRQ 0x1 /* Not Busy IRQ */ -#define WB_OVF 0x2 /* Write Buffer Overflow */ -#define WB_EDGE 0x4 /* Write Buffer Edge Detect */ -#define RD_RDY 0x8 /* Read Data Ready */ -#define WR_DONE 0x10 /* Page Write Done */ - -#define NAND_IS_512() (CONFIG_BFIN_NFC_CTL_VAL & 0x200) - -/* - * hardware specific access to control-lines - */ -static void bfin_nfc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ - pr_stamp(); - - if (cmd == NAND_CMD_NONE) - return; - - while (bfin_read_NFC_STAT() & WB_FULL) - continue; - - if (ctrl & NAND_CLE) - bfin_write_NFC_CMD(cmd); - else - bfin_write_NFC_ADDR(cmd); - SSYNC(); -} - -static int bfin_nfc_devready(struct mtd_info *mtd) -{ - pr_stamp(); - return (bfin_read_NFC_STAT() & NBUSY) ? 1 : 0; -} - -/* - * PIO mode for buffer writing and reading - */ -static void bfin_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) -{ - pr_stamp(); - - int i; - - /* - * Data reads are requested by first writing to NFC_DATA_RD - * and then reading back from NFC_READ. - */ - for (i = 0; i < len; ++i) { - while (bfin_read_NFC_STAT() & WB_FULL) - if (ctrlc()) - return; - - /* Contents do not matter */ - bfin_write_NFC_DATA_RD(0x0000); - SSYNC(); - - while (!(bfin_read_NFC_IRQSTAT() & RD_RDY)) - if (ctrlc()) - return; - - buf[i] = bfin_read_NFC_READ(); - - bfin_write_NFC_IRQSTAT(RD_RDY); - } -} - -static uint8_t bfin_nfc_read_byte(struct mtd_info *mtd) -{ - pr_stamp(); - - uint8_t val; - bfin_nfc_read_buf(mtd, &val, 1); - return val; -} - -static void bfin_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) -{ - pr_stamp(); - - int i; - - for (i = 0; i < len; ++i) { - while (bfin_read_NFC_STAT() & WB_FULL) - if (ctrlc()) - return; - - bfin_write_NFC_DATA_WR(buf[i]); - } - - /* Wait for the buffer to drain before we return */ - while (!(bfin_read_NFC_STAT() & WB_EMPTY)) - if (ctrlc()) - return; -} - -/* - * ECC functions - * These allow the bfin to use the controller's ECC - * generator block to ECC the data as it passes through - */ - -/* - * ECC error correction function - */ -static int bfin_nfc_correct_data_256(struct mtd_info *mtd, u_char *dat, - u_char *read_ecc, u_char *calc_ecc) -{ - u32 syndrome[5]; - u32 calced, stored; - unsigned short failing_bit, failing_byte; - u_char data; - - pr_stamp(); - - calced = calc_ecc[0] | (calc_ecc[1] << 8) | (calc_ecc[2] << 16); - stored = read_ecc[0] | (read_ecc[1] << 8) | (read_ecc[2] << 16); - - syndrome[0] = (calced ^ stored); - - /* - * syndrome 0: all zero - * No error in data - * No action - */ - if (!syndrome[0] || !calced || !stored) - return 0; - - /* - * sysdrome 0: only one bit is one - * ECC data was incorrect - * No action - */ - if (hweight32(syndrome[0]) == 1) - return 1; - - syndrome[1] = (calced & 0x7FF) ^ (stored & 0x7FF); - syndrome[2] = (calced & 0x7FF) ^ ((calced >> 11) & 0x7FF); - syndrome[3] = (stored & 0x7FF) ^ ((stored >> 11) & 0x7FF); - syndrome[4] = syndrome[2] ^ syndrome[3]; - - /* - * sysdrome 0: exactly 11 bits are one, each parity - * and parity' pair is 1 & 0 or 0 & 1. - * 1-bit correctable error - * Correct the error - */ - if (hweight32(syndrome[0]) == 11 && syndrome[4] == 0x7FF) { - failing_bit = syndrome[1] & 0x7; - failing_byte = syndrome[1] >> 0x3; - data = *(dat + failing_byte); - data = data ^ (0x1 << failing_bit); - *(dat + failing_byte) = data; - - return 0; - } - - /* - * sysdrome 0: random data - * More than 1-bit error, non-correctable error - * Discard data, mark bad block - */ - - return 1; -} - -static int bfin_nfc_correct_data(struct mtd_info *mtd, u_char *dat, - u_char *read_ecc, u_char *calc_ecc) -{ - int ret; - - pr_stamp(); - - ret = bfin_nfc_correct_data_256(mtd, dat, read_ecc, calc_ecc); - - /* If page size is 512, correct second 256 bytes */ - if (NAND_IS_512()) { - dat += 256; - read_ecc += 8; - calc_ecc += 8; - ret |= bfin_nfc_correct_data_256(mtd, dat, read_ecc, calc_ecc); - } - - return ret; -} - -static void reset_ecc(void) -{ - bfin_write_NFC_RST(0x1); - while (bfin_read_NFC_RST() & 1) - continue; -} - -static void bfin_nfc_enable_hwecc(struct mtd_info *mtd, int mode) -{ - reset_ecc(); -} - -static int bfin_nfc_calculate_ecc(struct mtd_info *mtd, - const u_char *dat, u_char *ecc_code) -{ - u16 ecc0, ecc1; - u32 code[2]; - u8 *p; - - pr_stamp(); - - /* first 4 bytes ECC code for 256 page size */ - ecc0 = bfin_read_NFC_ECC0(); - ecc1 = bfin_read_NFC_ECC1(); - - code[0] = (ecc0 & 0x7FF) | ((ecc1 & 0x7FF) << 11); - - /* first 3 bytes in ecc_code for 256 page size */ - p = (u8 *) code; - memcpy(ecc_code, p, 3); - - /* second 4 bytes ECC code for 512 page size */ - if (NAND_IS_512()) { - ecc0 = bfin_read_NFC_ECC2(); - ecc1 = bfin_read_NFC_ECC3(); - code[1] = (ecc0 & 0x7FF) | ((ecc1 & 0x7FF) << 11); - - /* second 3 bytes in ecc_code for second 256 - * bytes of 512 page size - */ - p = (u8 *) (code + 1); - memcpy((ecc_code + 3), p, 3); - } - - reset_ecc(); - - return 0; -} - -#ifdef CONFIG_BFIN_NFC_BOOTROM_ECC -# define BOOTROM_ECC 1 -#else -# define BOOTROM_ECC 0 -#endif - -static uint8_t bbt_pattern[] = { 0xff }; - -static struct nand_bbt_descr bootrom_bbt = { - .options = 0, - .offs = 63, - .len = 1, - .pattern = bbt_pattern, -}; - -static struct nand_ecclayout bootrom_ecclayout = { - .eccbytes = 24, - .eccpos = { - 0x8 * 0, 0x8 * 0 + 1, 0x8 * 0 + 2, - 0x8 * 1, 0x8 * 1 + 1, 0x8 * 1 + 2, - 0x8 * 2, 0x8 * 2 + 1, 0x8 * 2 + 2, - 0x8 * 3, 0x8 * 3 + 1, 0x8 * 3 + 2, - 0x8 * 4, 0x8 * 4 + 1, 0x8 * 4 + 2, - 0x8 * 5, 0x8 * 5 + 1, 0x8 * 5 + 2, - 0x8 * 6, 0x8 * 6 + 1, 0x8 * 6 + 2, - 0x8 * 7, 0x8 * 7 + 1, 0x8 * 7 + 2 - }, - .oobfree = { - { 0x8 * 0 + 3, 5 }, - { 0x8 * 1 + 3, 5 }, - { 0x8 * 2 + 3, 5 }, - { 0x8 * 3 + 3, 5 }, - { 0x8 * 4 + 3, 5 }, - { 0x8 * 5 + 3, 5 }, - { 0x8 * 6 + 3, 5 }, - { 0x8 * 7 + 3, 5 }, - } -}; - -/* - * Board-specific NAND initialization. The following members of the - * argument are board-specific (per include/linux/mtd/nand.h): - * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device - * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device - * - cmd_ctrl: hardwarespecific function for accesing control-lines - * - dev_ready: hardwarespecific function for accesing device ready/busy line - * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must - * only be provided if a hardware ECC is available - * - ecc.mode: mode of ecc, see defines - * - chip_delay: chip dependent delay for transfering data from array to - * read regs (tR) - * - options: various chip options. They can partly be set to inform - * nand_scan about special functionality. See the defines for further - * explanation - * Members with a "?" were not set in the merged testing-NAND branch, - * so they are not set here either. - */ -int board_nand_init(struct nand_chip *chip) -{ - const unsigned short pins[] = { - P_NAND_CE, P_NAND_RB, P_NAND_D0, P_NAND_D1, P_NAND_D2, - P_NAND_D3, P_NAND_D4, P_NAND_D5, P_NAND_D6, P_NAND_D7, - P_NAND_WE, P_NAND_RE, P_NAND_CLE, P_NAND_ALE, 0, - }; - - pr_stamp(); - - /* set width/ecc/timings/etc... */ - bfin_write_NFC_CTL(CONFIG_BFIN_NFC_CTL_VAL); - - /* clear interrupt status */ - bfin_write_NFC_IRQMASK(0x0); - bfin_write_NFC_IRQSTAT(0xffff); - - /* enable GPIO function enable register */ - peripheral_request_list(pins, "bfin_nand"); - - chip->cmd_ctrl = bfin_nfc_cmd_ctrl; - chip->read_buf = bfin_nfc_read_buf; - chip->write_buf = bfin_nfc_write_buf; - chip->read_byte = bfin_nfc_read_byte; - -#ifdef CONFIG_BFIN_NFC_NO_HW_ECC -# define ECC_HW 0 -#else -# define ECC_HW 1 -#endif - if (ECC_HW) { - if (BOOTROM_ECC) { - chip->badblock_pattern = &bootrom_bbt; - chip->ecc.layout = &bootrom_ecclayout; - } - if (!NAND_IS_512()) { - chip->ecc.bytes = 3; - chip->ecc.size = 256; - chip->ecc.strength = 1; - } else { - chip->ecc.bytes = 6; - chip->ecc.size = 512; - chip->ecc.strength = 2; - } - chip->ecc.mode = NAND_ECC_HW; - chip->ecc.calculate = bfin_nfc_calculate_ecc; - chip->ecc.correct = bfin_nfc_correct_data; - chip->ecc.hwctl = bfin_nfc_enable_hwecc; - } else - chip->ecc.mode = NAND_ECC_SOFT; - chip->dev_ready = bfin_nfc_devready; - chip->chip_delay = 0; - - return 0; -} diff --git a/drivers/net/Makefile b/drivers/net/Makefile index ac7e07bfdf5..aedb2cc90d9 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o obj-$(CONFIG_DRIVER_AX88180) += ax88180.o obj-$(CONFIG_BCM_SF2_ETH) += bcm-sf2-eth.o obj-$(CONFIG_BCM_SF2_ETH_GMAC) += bcm-sf2-eth-gmac.o -obj-$(CONFIG_BFIN_MAC) += bfin_mac.o obj-$(CONFIG_CALXEDA_XGMAC) += calxedaxgmac.o obj-$(CONFIG_CS8900) += cs8900.o obj-$(CONFIG_TULIP) += dc2114x.o diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c deleted file mode 100644 index 26a626b4cbd..00000000000 --- a/drivers/net/bfin_mac.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Driver for Blackfin On-Chip MAC device - * - * Copyright (c) 2005-2008 Analog Device, Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "bfin_mac.h" - -#ifndef CONFIG_PHY_ADDR -# define CONFIG_PHY_ADDR 1 -#endif -#ifndef CONFIG_PHY_CLOCK_FREQ -# define CONFIG_PHY_CLOCK_FREQ 2500000 -#endif - -#ifdef CONFIG_POST -#include -#endif - -#define RXBUF_BASE_ADDR 0xFF900000 -#define TXBUF_BASE_ADDR 0xFF800000 -#define TX_BUF_CNT 1 - -#define TOUT_LOOP 1000000 - -static ADI_ETHER_BUFFER *txbuf[TX_BUF_CNT]; -static ADI_ETHER_BUFFER *rxbuf[PKTBUFSRX]; -static u16 txIdx; /* index of the current RX buffer */ -static u16 rxIdx; /* index of the current TX buffer */ - -/* DMAx_CONFIG values at DMA Restart */ -static const union { - u16 data; - ADI_DMA_CONFIG_REG reg; -} txdmacfg = { - .reg = { - .b_DMA_EN = 1, /* enabled */ - .b_WNR = 0, /* read from memory */ - .b_WDSIZE = 2, /* wordsize is 32 bits */ - .b_DMA2D = 0, - .b_RESTART = 0, - .b_DI_SEL = 0, - .b_DI_EN = 0, /* no interrupt */ - .b_NDSIZE = 5, /* 5 half words is desc size */ - .b_FLOW = 7 /* large desc flow */ - }, -}; - -static int bfin_miiphy_wait(void) -{ - /* poll the STABUSY bit */ - while (bfin_read_EMAC_STAADD() & STABUSY) - continue; - return 0; -} - -static int bfin_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg) -{ - ushort val = 0; - if (bfin_miiphy_wait()) - return 1; - bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STABUSY); - if (bfin_miiphy_wait()) - return 1; - val = bfin_read_EMAC_STADAT(); - return val; -} - -static int bfin_miiphy_write(struct mii_dev *bus, int addr, int devad, - int reg, u16 val) -{ - if (bfin_miiphy_wait()) - return 1; - bfin_write_EMAC_STADAT(val); - bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STAOP | STABUSY); - return 0; -} - -int bfin_EMAC_initialize(bd_t *bis) -{ - struct eth_device *dev; - dev = malloc(sizeof(*dev)); - if (dev == NULL) - hang(); - - memset(dev, 0, sizeof(*dev)); - strcpy(dev->name, "bfin_mac"); - - dev->iobase = 0; - dev->priv = 0; - dev->init = bfin_EMAC_init; - dev->halt = bfin_EMAC_halt; - dev->send = bfin_EMAC_send; - dev->recv = bfin_EMAC_recv; - dev->write_hwaddr = bfin_EMAC_setup_addr; - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - int retval; - struct mii_dev *mdiodev = mdio_alloc(); - if (!mdiodev) - return -ENOMEM; - strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); - mdiodev->read = bfin_miiphy_read; - mdiodev->write = bfin_miiphy_write; - - retval = mdio_register(mdiodev); - if (retval < 0) - return retval; - - dev->priv = mdiodev; -#endif - - return 0; -} - -static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length) -{ - int i; - int result = 0; - - if (length <= 0) { - printf("Ethernet: bad packet size: %d\n", length); - goto out; - } - - if (bfin_read_DMA2_IRQ_STATUS() & DMA_ERR) { - printf("Ethernet: tx DMA error\n"); - goto out; - } - - for (i = 0; (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN); ++i) { - if (i > TOUT_LOOP) { - puts("Ethernet: tx time out\n"); - goto out; - } - } - txbuf[txIdx]->FrmData->NoBytes = length; - memcpy(txbuf[txIdx]->FrmData->Dest, (void *)packet, length); - txbuf[txIdx]->Dma[0].START_ADDR = (u32) txbuf[txIdx]->FrmData; - bfin_write_DMA2_NEXT_DESC_PTR(txbuf[txIdx]->Dma); - bfin_write_DMA2_CONFIG(txdmacfg.data); - bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE); - - for (i = 0; (txbuf[txIdx]->StatusWord & TX_COMP) == 0; i++) { - if (i > TOUT_LOOP) { - puts("Ethernet: tx error\n"); - goto out; - } - } - result = txbuf[txIdx]->StatusWord; - txbuf[txIdx]->StatusWord = 0; - if ((txIdx + 1) >= TX_BUF_CNT) - txIdx = 0; - else - txIdx++; - out: - debug("BFIN EMAC send: length = %d\n", length); - return result; -} - -static int bfin_EMAC_recv(struct eth_device *dev) -{ - int length = 0; - - for (;;) { - if ((rxbuf[rxIdx]->StatusWord & RX_COMP) == 0) { - length = -1; - break; - } - if ((rxbuf[rxIdx]->StatusWord & RX_DMAO) != 0) { - printf("Ethernet: rx dma overrun\n"); - break; - } - if ((rxbuf[rxIdx]->StatusWord & RX_OK) == 0) { - printf("Ethernet: rx error\n"); - break; - } - length = rxbuf[rxIdx]->StatusWord & 0x000007FF; - if (length <= 4) { - printf("Ethernet: bad frame\n"); - break; - } - - debug("%s: len = %d\n", __func__, length - 4); - - net_rx_packets[rxIdx] = rxbuf[rxIdx]->FrmData->Dest; - net_process_received_packet(net_rx_packets[rxIdx], length - 4); - bfin_write_DMA1_IRQ_STATUS(DMA_DONE | DMA_ERR); - rxbuf[rxIdx]->StatusWord = 0x00000000; - if ((rxIdx + 1) >= PKTBUFSRX) - rxIdx = 0; - else - rxIdx++; - } - - return length; -} - -/************************************************************** - * - * Ethernet Initialization Routine - * - *************************************************************/ - -/* MDC = SCLK / MDC_freq / 2 - 1 */ -#define MDC_FREQ_TO_DIV(mdc_freq) (get_sclk() / (mdc_freq) / 2 - 1) - -#ifndef CONFIG_BFIN_MAC_PINS -# ifdef CONFIG_RMII -# define CONFIG_BFIN_MAC_PINS P_RMII0 -# else -# define CONFIG_BFIN_MAC_PINS P_MII0 -# endif -#endif - -static int bfin_miiphy_init(struct eth_device *dev, int *opmode) -{ - const unsigned short pins[] = CONFIG_BFIN_MAC_PINS; - int phydat; - size_t count; - struct mii_dev *mdiodev = dev->priv; - - /* Enable PHY output */ - bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE); - - /* Set all the pins to peripheral mode */ - peripheral_request_list(pins, "bfin_mac"); - - /* Odd word alignment for Receive Frame DMA word */ - /* Configure checksum support and rcve frame word alignment */ - bfin_write_EMAC_SYSCTL(RXDWA | RXCKS | SET_MDCDIV(MDC_FREQ_TO_DIV(CONFIG_PHY_CLOCK_FREQ))); - - /* turn on auto-negotiation and wait for link to come up */ - bfin_miiphy_write(mdiodev, CONFIG_PHY_ADDR, MDIO_DEVAD_NONE, MII_BMCR, - BMCR_ANENABLE); - count = 0; - while (1) { - ++count; - phydat = bfin_miiphy_read(mdiodev, CONFIG_PHY_ADDR, - MDIO_DEVAD_NONE, MII_BMSR); - if (phydat < 0) - return phydat; - if (phydat & BMSR_LSTATUS) - break; - if (count > 30000) { - printf("%s: link down, check cable\n", dev->name); - return -1; - } - udelay(100); - } - - /* see what kind of link we have */ - phydat = bfin_miiphy_read(mdiodev, CONFIG_PHY_ADDR, MDIO_DEVAD_NONE, - MII_LPA); - if (phydat < 0) - return phydat; - if (phydat & LPA_DUPLEX) - *opmode = FDMODE; - else - *opmode = 0; - - bfin_write_EMAC_MMC_CTL(RSTC | CROLL); - bfin_write_EMAC_VLAN1(EMAC_VLANX_DEF_VAL); - bfin_write_EMAC_VLAN2(EMAC_VLANX_DEF_VAL); - - /* Initialize the TX DMA channel registers */ - bfin_write_DMA2_X_COUNT(0); - bfin_write_DMA2_X_MODIFY(4); - bfin_write_DMA2_Y_COUNT(0); - bfin_write_DMA2_Y_MODIFY(0); - - /* Initialize the RX DMA channel registers */ - bfin_write_DMA1_X_COUNT(0); - bfin_write_DMA1_X_MODIFY(4); - bfin_write_DMA1_Y_COUNT(0); - bfin_write_DMA1_Y_MODIFY(0); - - return 0; -} - -static int bfin_EMAC_setup_addr(struct eth_device *dev) -{ - bfin_write_EMAC_ADDRLO( - dev->enetaddr[0] | - dev->enetaddr[1] << 8 | - dev->enetaddr[2] << 16 | - dev->enetaddr[3] << 24 - ); - bfin_write_EMAC_ADDRHI( - dev->enetaddr[4] | - dev->enetaddr[5] << 8 - ); - return 0; -} - -static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd) -{ - u32 opmode; - int dat; - int i; - debug("Eth_init: ......\n"); - - txIdx = 0; - rxIdx = 0; - - /* Initialize System Register */ - if (bfin_miiphy_init(dev, &dat) < 0) - return -1; - - /* Initialize EMAC address */ - bfin_EMAC_setup_addr(dev); - - /* Initialize TX and RX buffer */ - for (i = 0; i < PKTBUFSRX; i++) { - rxbuf[i] = SetupRxBuffer(i); - if (i > 0) { - rxbuf[i - 1]->Dma[1].NEXT_DESC_PTR = rxbuf[i]->Dma; - if (i == (PKTBUFSRX - 1)) - rxbuf[i]->Dma[1].NEXT_DESC_PTR = rxbuf[0]->Dma; - } - } - for (i = 0; i < TX_BUF_CNT; i++) { - txbuf[i] = SetupTxBuffer(i); - if (i > 0) { - txbuf[i - 1]->Dma[1].NEXT_DESC_PTR = txbuf[i]->Dma; - if (i == (TX_BUF_CNT - 1)) - txbuf[i]->Dma[1].NEXT_DESC_PTR = txbuf[0]->Dma; - } - } - - /* Set RX DMA */ - bfin_write_DMA1_NEXT_DESC_PTR(rxbuf[0]->Dma); - bfin_write_DMA1_CONFIG(rxbuf[0]->Dma[0].CONFIG_DATA); - - /* Wait MII done */ - bfin_miiphy_wait(); - - /* We enable only RX here */ - /* ASTP : Enable Automatic Pad Stripping - PR : Promiscuous Mode for test - PSF : Receive frames with total length less than 64 bytes. - FDMODE : Full Duplex Mode - LB : Internal Loopback for test - RE : Receiver Enable */ - if (dat == FDMODE) - opmode = ASTP | FDMODE | PSF; - else - opmode = ASTP | PSF; - opmode |= RE; -#ifdef CONFIG_RMII - opmode |= TE | RMII; -#endif - /* Turn on the EMAC */ - bfin_write_EMAC_OPMODE(opmode); - return 0; -} - -static void bfin_EMAC_halt(struct eth_device *dev) -{ - debug("Eth_halt: ......\n"); - /* Turn off the EMAC */ - bfin_write_EMAC_OPMODE(0); - /* Turn off the EMAC RX DMA */ - bfin_write_DMA1_CONFIG(0); - bfin_write_DMA2_CONFIG(0); -} - -ADI_ETHER_BUFFER *SetupRxBuffer(int no) -{ - ADI_ETHER_FRAME_BUFFER *frmbuf; - ADI_ETHER_BUFFER *buf; - int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2; /* ensure a multi. of 4 */ - int total_size = nobytes_buffer + RECV_BUFSIZE; - - buf = (void *) (RXBUF_BASE_ADDR + no * total_size); - frmbuf = (void *) (RXBUF_BASE_ADDR + no * total_size + nobytes_buffer); - - memset(buf, 0x00, nobytes_buffer); - buf->FrmData = frmbuf; - memset(frmbuf, 0xfe, RECV_BUFSIZE); - - /* set up first desc to point to receive frame buffer */ - buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]); - buf->Dma[0].START_ADDR = (u32) buf->FrmData; - buf->Dma[0].CONFIG.b_DMA_EN = 1; /* enabled */ - buf->Dma[0].CONFIG.b_WNR = 1; /* Write to memory */ - buf->Dma[0].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */ - buf->Dma[0].CONFIG.b_NDSIZE = 5; /* 5 half words is desc size. */ - buf->Dma[0].CONFIG.b_FLOW = 7; /* large desc flow */ - - /* set up second desc to point to status word */ - buf->Dma[1].NEXT_DESC_PTR = buf->Dma; - buf->Dma[1].START_ADDR = (u32) & buf->IPHdrChksum; - buf->Dma[1].CONFIG.b_DMA_EN = 1; /* enabled */ - buf->Dma[1].CONFIG.b_WNR = 1; /* Write to memory */ - buf->Dma[1].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */ - buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */ - buf->Dma[1].CONFIG.b_NDSIZE = 5; /* must be 0 when FLOW is 0 */ - buf->Dma[1].CONFIG.b_FLOW = 7; /* stop */ - - return buf; -} - -ADI_ETHER_BUFFER *SetupTxBuffer(int no) -{ - ADI_ETHER_FRAME_BUFFER *frmbuf; - ADI_ETHER_BUFFER *buf; - int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2; /* ensure a multi. of 4 */ - int total_size = nobytes_buffer + RECV_BUFSIZE; - - buf = (void *) (TXBUF_BASE_ADDR + no * total_size); - frmbuf = (void *) (TXBUF_BASE_ADDR + no * total_size + nobytes_buffer); - - memset(buf, 0x00, nobytes_buffer); - buf->FrmData = frmbuf; - memset(frmbuf, 0x00, RECV_BUFSIZE); - - /* set up first desc to point to receive frame buffer */ - buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]); - buf->Dma[0].START_ADDR = (u32) buf->FrmData; - buf->Dma[0].CONFIG.b_DMA_EN = 1; /* enabled */ - buf->Dma[0].CONFIG.b_WNR = 0; /* Read to memory */ - buf->Dma[0].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */ - buf->Dma[0].CONFIG.b_NDSIZE = 5; /* 5 half words is desc size. */ - buf->Dma[0].CONFIG.b_FLOW = 7; /* large desc flow */ - - /* set up second desc to point to status word */ - buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]); - buf->Dma[1].START_ADDR = (u32) & buf->StatusWord; - buf->Dma[1].CONFIG.b_DMA_EN = 1; /* enabled */ - buf->Dma[1].CONFIG.b_WNR = 1; /* Write to memory */ - buf->Dma[1].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */ - buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */ - buf->Dma[1].CONFIG.b_NDSIZE = 0; /* must be 0 when FLOW is 0 */ - buf->Dma[1].CONFIG.b_FLOW = 0; /* stop */ - - return buf; -} - -#if defined(CONFIG_POST) && defined(CONFIG_SYS_POST_ETHER) -int ether_post_test(int flags) -{ - uchar buf[64]; - int i, value = 0; - int length; - uint addr; - - printf("\n--------"); - bfin_EMAC_init(NULL, NULL); - /* construct the package */ - addr = bfin_read_EMAC_ADDRLO(); - buf[0] = buf[6] = addr; - buf[1] = buf[7] = addr >> 8; - buf[2] = buf[8] = addr >> 16; - buf[3] = buf[9] = addr >> 24; - addr = bfin_read_EMAC_ADDRHI(); - buf[4] = buf[10] = addr; - buf[5] = buf[11] = addr >> 8; - buf[12] = 0x08; /* Type: ARP */ - buf[13] = 0x06; - buf[14] = 0x00; /* Hardware type: Ethernet */ - buf[15] = 0x01; - buf[16] = 0x08; /* Protocal type: IP */ - buf[17] = 0x00; - buf[18] = 0x06; /* Hardware size */ - buf[19] = 0x04; /* Protocol size */ - buf[20] = 0x00; /* Opcode: request */ - buf[21] = 0x01; - - for (i = 0; i < 42; i++) - buf[i + 22] = i; - printf("--------Send 64 bytes......\n"); - bfin_EMAC_send(NULL, buf, 64); - for (i = 0; i < 100; i++) { - udelay(10000); - if ((rxbuf[rxIdx]->StatusWord & RX_COMP) != 0) { - value = 1; - break; - } - } - if (value == 0) { - printf("--------EMAC can't receive any data\n"); - eth_halt(); - return -1; - } - length = rxbuf[rxIdx]->StatusWord & 0x000007FF - 4; - for (i = 0; i < length; i++) { - if (rxbuf[rxIdx]->FrmData->Dest[i] != buf[i]) { - printf("--------EMAC receive error data!\n"); - eth_halt(); - return -1; - } - } - printf("--------receive %d bytes, matched\n", length); - bfin_EMAC_halt(NULL); - return 0; -} -#endif diff --git a/drivers/net/bfin_mac.h b/drivers/net/bfin_mac.h deleted file mode 100644 index 54ffb3830e2..00000000000 --- a/drivers/net/bfin_mac.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * bfin_mac.h - some defines/structures for the Blackfin on-chip MAC. - * - * Copyright (c) 2005-2008 Analog Device, Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef __BFIN_MAC_H__ -#define __BFIN_MAC_H__ - -#define RECV_BUFSIZE (0x614) - -typedef struct ADI_DMA_CONFIG_REG { - u16 b_DMA_EN:1; /* 0 Enabled */ - u16 b_WNR:1; /* 1 Direction */ - u16 b_WDSIZE:2; /* 2:3 Transfer word size */ - u16 b_DMA2D:1; /* 4 DMA mode */ - u16 b_RESTART:1; /* 5 Retain FIFO */ - u16 b_DI_SEL:1; /* 6 Data interrupt timing select */ - u16 b_DI_EN:1; /* 7 Data interrupt enabled */ - u16 b_NDSIZE:4; /* 8:11 Flex descriptor size */ - u16 b_FLOW:3; /* 12:14Flow */ -} ADI_DMA_CONFIG_REG; - -typedef struct adi_ether_frame_buffer { - u16 NoBytes; /* the no. of following bytes */ - u8 Dest[6]; /* destination MAC address */ - u8 Srce[6]; /* source MAC address */ - u16 LTfield; /* length/type field */ - u8 Data[0]; /* payload bytes */ -} ADI_ETHER_FRAME_BUFFER; -/* 16 bytes/struct */ - -typedef struct dma_descriptor { - struct dma_descriptor *NEXT_DESC_PTR; - u32 START_ADDR; - union { - u16 CONFIG_DATA; - ADI_DMA_CONFIG_REG CONFIG; - }; -} DMA_DESCRIPTOR; -/* 10 bytes/struct in 12 bytes */ - -typedef struct adi_ether_buffer { - DMA_DESCRIPTOR Dma[2]; /* first for the frame, second for the status */ - ADI_ETHER_FRAME_BUFFER *FrmData;/* pointer to data */ - struct adi_ether_buffer *pNext; /* next buffer */ - struct adi_ether_buffer *pPrev; /* prev buffer */ - u16 IPHdrChksum; /* the IP header checksum */ - u16 IPPayloadChksum; /* the IP header and payload checksum */ - volatile u32 StatusWord; /* the frame status word */ -} ADI_ETHER_BUFFER; -/* 40 bytes/struct in 44 bytes */ - -static ADI_ETHER_BUFFER *SetupRxBuffer(int no); -static ADI_ETHER_BUFFER *SetupTxBuffer(int no); - -static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd); -static void bfin_EMAC_halt(struct eth_device *dev); -static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length); -static int bfin_EMAC_recv(struct eth_device *dev); -static int bfin_EMAC_setup_addr(struct eth_device *dev); - -#endif diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index c9194270851..87c3d9cae20 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_DM_RTC) += rtc-uclass.o obj-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o -obj-$(CONFIG_RTC_BFIN) += bfin_rtc.o obj-y += date.o obj-$(CONFIG_RTC_DAVINCI) += davinci.o obj-$(CONFIG_RTC_DS1302) += ds1302.o diff --git a/drivers/rtc/bfin_rtc.c b/drivers/rtc/bfin_rtc.c deleted file mode 100644 index a079a1d4723..00000000000 --- a/drivers/rtc/bfin_rtc.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2004-2008 Analog Devices Inc. - * - * (C) Copyright 2001 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include - -#if defined(CONFIG_CMD_DATE) - -#include -#include - -#define pr_stamp() debug("%s:%s:%i: here i am\n", __FILE__, __func__, __LINE__) - -#define MIN_TO_SECS(x) (60 * (x)) -#define HRS_TO_SECS(x) (60 * MIN_TO_SECS(x)) -#define DAYS_TO_SECS(x) (24 * HRS_TO_SECS(x)) - -#define NUM_SECS_IN_MIN MIN_TO_SECS(1) -#define NUM_SECS_IN_HR HRS_TO_SECS(1) -#define NUM_SECS_IN_DAY DAYS_TO_SECS(1) - -/* Enable the RTC prescaler enable register */ -void rtc_init(void) -{ - if (!(bfin_read_RTC_PREN() & 0x1)) - bfin_write_RTC_PREN(0x1); -} - -/* Our on-chip RTC has no notion of "reset" */ -void rtc_reset(void) -{ - rtc_init(); -} - -/* Wait for pending writes to complete */ -static void wait_for_complete(void) -{ - pr_stamp(); - while (!(bfin_read_RTC_ISTAT() & WRITE_COMPLETE)) - if (!(bfin_read_RTC_ISTAT() & WRITE_PENDING)) - break; - bfin_write_RTC_ISTAT(WRITE_COMPLETE); -} - -/* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers - * based on this value. - */ -int rtc_set(struct rtc_time *tmp) -{ - unsigned long remain, days, hrs, mins, secs; - - pr_stamp(); - - if (tmp == NULL) { - puts("Error setting the date/time\n"); - return -1; - } - - rtc_init(); - wait_for_complete(); - - /* Calculate number of seconds this incoming time represents */ - remain = rtc_mktime(tmp); - - /* Figure out how many days since epoch */ - days = remain / NUM_SECS_IN_DAY; - - /* From the remaining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */ - remain = remain % NUM_SECS_IN_DAY; - hrs = remain / NUM_SECS_IN_HR; - remain = remain % NUM_SECS_IN_HR; - mins = remain / NUM_SECS_IN_MIN; - secs = remain % NUM_SECS_IN_MIN; - - /* Encode these time values into our RTC_STAT register */ - bfin_write_RTC_STAT(SET_ALARM(days, hrs, mins, secs)); - - return 0; -} - -/* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */ -int rtc_get(struct rtc_time *tmp) -{ - uint32_t cur_rtc_stat; - int time_in_sec; - int tm_sec, tm_min, tm_hr, tm_day; - - pr_stamp(); - - if (tmp == NULL) { - puts("Error getting the date/time\n"); - return -1; - } - - rtc_init(); - wait_for_complete(); - - /* Read the RTC_STAT register */ - cur_rtc_stat = bfin_read_RTC_STAT(); - - /* Convert our encoded format into actual time values */ - tm_sec = (cur_rtc_stat & RTC_SEC) >> RTC_SEC_P; - tm_min = (cur_rtc_stat & RTC_MIN) >> RTC_MIN_P; - tm_hr = (cur_rtc_stat & RTC_HR ) >> RTC_HR_P; - tm_day = (cur_rtc_stat & RTC_DAY) >> RTC_DAY_P; - - /* Calculate the total number of seconds since epoch */ - time_in_sec = (tm_sec) + MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hr) + DAYS_TO_SECS(tm_day); - rtc_to_tm(time_in_sec, tmp); - - return 0; -} - -#endif diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index dea18363caa..36745ca9c99 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -12,7 +12,6 @@ obj-y += imx_watchdog.o endif obj-$(CONFIG_S5P) += s5p_wdt.o obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o -obj-$(CONFIG_BFIN_WATCHDOG) += bfin_wdt.o obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c deleted file mode 100644 index 6a8db59fdff..00000000000 --- a/drivers/watchdog/bfin_wdt.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * watchdog.c - driver for Blackfin on-chip watchdog - * - * Copyright (c) 2007-2009 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include - -void hw_watchdog_reset(void) -{ - bfin_write_WDOG_STAT(0); -} - -void hw_watchdog_init(void) -{ - bfin_write_WDOG_CTL(WDDIS); - SSYNC(); - bfin_write_WDOG_CNT(CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000 * get_sclk()); - hw_watchdog_reset(); - bfin_write_WDOG_CTL(WDEN); -} -- cgit v1.3.1 From 573a3811edc89c2ea3bf4fd077e3673b863b9a0d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 14 Apr 2017 11:10:24 +0900 Subject: sysreset: psci: support system reset in a generic way with PSCI If the system is running PSCI firmware, the System Reset function (func ID: 0x80000009) is supposed to be handled by PSCI, that is, the SoC/board specific reset implementation should be moved to PSCI. U-Boot should call the PSCI service according to the arm-smccc manner. The arm-smccc is supported on ARMv7 or later. Especially, ARMv8 generation SoCs are likely to run ARM Trusted Firmware BL31. In this case, U-Boot is a non-secure world boot loader, so it should not be able to reset the system directly. Signed-off-by: Masahiro Yamada --- arch/arm/Kconfig | 1 + drivers/Kconfig | 2 + drivers/Makefile | 5 +- drivers/firmware/Kconfig | 6 +++ drivers/firmware/Makefile | 2 + drivers/firmware/firmware-uclass.c | 11 +++++ drivers/firmware/psci.c | 94 ++++++++++++++++++++++++++++++++++++++ drivers/sysreset/Kconfig | 10 ++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_psci.c | 41 +++++++++++++++++ include/dm/uclass-id.h | 1 + include/linux/psci.h | 13 ++++++ 12 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 drivers/firmware/Kconfig create mode 100644 drivers/firmware/Makefile create mode 100644 drivers/firmware/firmware-uclass.c create mode 100644 drivers/firmware/psci.c create mode 100644 drivers/sysreset/sysreset_psci.c (limited to 'drivers') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 16578b8b389..7812f21f36b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -177,6 +177,7 @@ config SYS_CACHELINE_SIZE config ARM_SMCCC bool "Support for ARM SMC Calling Convention (SMCCC)" depends on CPU_V7 || ARM64 + select ARM_PSCI_FW help Say Y here if you want to enable ARM SMC Calling Convention. This should be enabled if U-Boot needs to communicate with system diff --git a/drivers/Kconfig b/drivers/Kconfig index 3e6bbacd15c..a096dad2b22 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -24,6 +24,8 @@ source "drivers/dfu/Kconfig" source "drivers/dma/Kconfig" +source "drivers/firmware/Kconfig" + source "drivers/fpga/Kconfig" source "drivers/gpio/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 5d8baa5a1fe..4a4b2377c58 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -23,7 +23,7 @@ obj-$(CONFIG_SPL_SERIAL_SUPPORT) += serial/ obj-$(CONFIG_SPL_SPI_SUPPORT) += spi/ obj-$(CONFIG_SPL_POWER_SUPPORT) += power/ power/pmic/ obj-$(CONFIG_SPL_POWER_SUPPORT) += power/regulator/ -obj-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/ +obj-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/ obj-$(CONFIG_SPL_MTD_SUPPORT) += mtd/ obj-$(CONFIG_SPL_NAND_SUPPORT) += mtd/nand/ obj-$(CONFIG_SPL_ONENAND_SUPPORT) += mtd/onenand/ @@ -52,7 +52,7 @@ endif ifdef CONFIG_TPL_BUILD obj-$(CONFIG_TPL_I2C_SUPPORT) += i2c/ -obj-$(CONFIG_TPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/ +obj-$(CONFIG_TPL_DRIVERS_MISC_SUPPORT) += misc/ sysreset/ firmware/ obj-$(CONFIG_TPL_MMC_SUPPORT) += mmc/ obj-$(CONFIG_TPL_MPC8XXX_INIT_DDR_SUPPORT) += ddr/fsl/ obj-$(CONFIG_TPL_NAND_SUPPORT) += mtd/nand/ @@ -71,6 +71,7 @@ obj-y += block/ obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/ obj-$(CONFIG_CPU) += cpu/ obj-y += crypto/ +obj-y += firmware/ obj-$(CONFIG_FPGA) += fpga/ obj-y += hwmon/ obj-y += misc/ diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig new file mode 100644 index 00000000000..4c32426e0ec --- /dev/null +++ b/drivers/firmware/Kconfig @@ -0,0 +1,6 @@ +config FIRMWARE + bool + +config ARM_PSCI_FW + bool + select FIRMWARE diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile new file mode 100644 index 00000000000..b2082553684 --- /dev/null +++ b/drivers/firmware/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_FIRMWARE) += firmware-uclass.o +obj-$(CONFIG_ARM_PSCI_FW) += psci.o diff --git a/drivers/firmware/firmware-uclass.c b/drivers/firmware/firmware-uclass.c new file mode 100644 index 00000000000..01b6a44b9d3 --- /dev/null +++ b/drivers/firmware/firmware-uclass.c @@ -0,0 +1,11 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +/* Firmware access is platform-dependent. No generic code in uclass */ +UCLASS_DRIVER(firmware) = { + .id = UCLASS_FIRMWARE, + .name = "firmware", +}; diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c new file mode 100644 index 00000000000..40fba6432ce --- /dev/null +++ b/drivers/firmware/psci.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2017 Masahiro Yamada + * + * Based on drivers/firmware/psci.c from Linux: + * Copyright (C) 2015 ARM Limited + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +psci_fn *invoke_psci_fn; + +static unsigned long __invoke_psci_fn_hvc(unsigned long function_id, + unsigned long arg0, unsigned long arg1, + unsigned long arg2) +{ + struct arm_smccc_res res; + + arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res); + return res.a0; +} + +static unsigned long __invoke_psci_fn_smc(unsigned long function_id, + unsigned long arg0, unsigned long arg1, + unsigned long arg2) +{ + struct arm_smccc_res res; + + arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res); + return res.a0; +} + +static int psci_bind(struct udevice *dev) +{ + /* No SYSTEM_RESET support for PSCI 0.1 */ + if (of_device_is_compatible(dev, "arm,psci-0.2") || + of_device_is_compatible(dev, "arm,psci-1.0")) { + int ret; + + /* bind psci-sysreset optionally */ + ret = device_bind_driver(dev, "psci-sysreset", "psci-sysreset", + NULL); + if (ret) + debug("PSCI System Reset was not bound.\n"); + } + + return 0; +} + +static int psci_probe(struct udevice *dev) +{ + DECLARE_GLOBAL_DATA_PTR; + const char *method; + + method = fdt_stringlist_get(gd->fdt_blob, dev->of_offset, "method", 0, + NULL); + if (!method) { + printf("missing \"method\" property\n"); + return -ENXIO; + } + + if (!strcmp("hvc", method)) { + invoke_psci_fn = __invoke_psci_fn_hvc; + } else if (!strcmp("smc", method)) { + invoke_psci_fn = __invoke_psci_fn_smc; + } else { + printf("invalid \"method\" property: %s\n", method); + return -EINVAL; + } + + return 0; +} + +static const struct udevice_id psci_of_match[] = { + { .compatible = "arm,psci" }, + { .compatible = "arm,psci-0.2" }, + { .compatible = "arm,psci-1.0" }, + {}, +}; + +U_BOOT_DRIVER(psci) = { + .name = "psci", + .id = UCLASS_FIRMWARE, + .of_match = psci_of_match, + .bind = psci_bind, + .probe = psci_probe, +}; diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 05a37b9a14c..966463036f1 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -13,4 +13,14 @@ config SYSRESET to effect a reset. The uclass will try all available drivers when reset_walk() is called. +if SYSRESET + +config SYSRESET_PSCI + bool "Enable support for PSCI System Reset" + depends on ARM_PSCI_FW + help + Enable PSCI SYSTEM_RESET function call. To use this, PSCI firmware + must be running on your system. + +endif endmenu diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index 49b8bb61c63..7bb840649ff 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -5,6 +5,7 @@ # obj-$(CONFIG_SYSRESET) += sysreset-uclass.o +obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_ROCKCHIP_RK3036) += sysreset_rk3036.o diff --git a/drivers/sysreset/sysreset_psci.c b/drivers/sysreset/sysreset_psci.c new file mode 100644 index 00000000000..a4911b7d8ff --- /dev/null +++ b/drivers/sysreset/sysreset_psci.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static int psci_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + unsigned long function_id; + + switch (type) { + case SYSRESET_WARM: + case SYSRESET_COLD: + function_id = PSCI_0_2_FN_SYSTEM_RESET; + break; + case SYSRESET_POWER: + function_id = PSCI_0_2_FN_SYSTEM_OFF; + break; + default: + return -ENOSYS; + } + + invoke_psci_fn(function_id, 0, 0, 0); + + return -EINPROGRESS; +} + +static struct sysreset_ops psci_sysreset_ops = { + .request = psci_sysreset_request, +}; + +U_BOOT_DRIVER(psci_sysreset) = { + .name = "psci-sysreset", + .id = UCLASS_SYSRESET, + .ops = &psci_sysreset_ops, +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 8c92d0b0308..1b635e41103 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -35,6 +35,7 @@ enum uclass_id { UCLASS_DMA, /* Direct Memory Access */ UCLASS_ETH, /* Ethernet device */ UCLASS_GPIO, /* Bank of general-purpose I/O pins */ + UCLASS_FIRMWARE, /* Firmware */ UCLASS_I2C, /* I2C bus */ UCLASS_I2C_EEPROM, /* I2C EEPROM device */ UCLASS_I2C_GENERIC, /* Generic I2C device */ diff --git a/include/linux/psci.h b/include/linux/psci.h index 310d83e0a91..8d13bd27021 100644 --- a/include/linux/psci.h +++ b/include/linux/psci.h @@ -87,4 +87,17 @@ #define PSCI_RET_NOT_PRESENT -7 #define PSCI_RET_DISABLED -8 +#ifdef CONFIG_ARM_PSCI_FW +typedef unsigned long (psci_fn)(unsigned long, unsigned long, + unsigned long, unsigned long); + +extern psci_fn *invoke_psci_fn; +#else +unsigned long invoke_psci_fn(unsigned long a0, unsigned long a1, + unsigned long a2, unsigned long a3) +{ + return PSCI_RET_DISABLED; +} +#endif + #endif /* _UAPI_LINUX_PSCI_H */ -- cgit v1.3.1 From 73be5b3fa73e329ad0d9e12db427cd665e1a483c Mon Sep 17 00:00:00 2001 From: "xypron.glpk@gmx.de" Date: Sat, 15 Apr 2017 15:05:46 +0200 Subject: usbtty: avoid potential NULL pointer dereference If current_urb is NULL it should not be dereferenced. The problem was indicated by cppcheck. Signed-off-by: Heinrich Schuchardt Reviewed-by: Tom Rini --- drivers/serial/usbtty.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c index 2e19813643b..29799dce93a 100644 --- a/drivers/serial/usbtty.c +++ b/drivers/serial/usbtty.c @@ -850,6 +850,13 @@ static int write_buffer (circbuf_t * buf) struct urb *current_urb = NULL; current_urb = next_urb (device_instance, endpoint); + + if (!current_urb) { + TTYERR ("current_urb is NULL, buf->size %d\n", + buf->size); + return 0; + } + /* TX data still exists - send it now */ if(endpoint->sent < current_urb->actual_length){ @@ -871,12 +878,6 @@ static int write_buffer (circbuf_t * buf) */ while (buf->size > 0) { - if (!current_urb) { - TTYERR ("current_urb is NULL, buf->size %d\n", - buf->size); - return total; - } - dest = (char*)current_urb->buffer + current_urb->actual_length; -- cgit v1.3.1 From ea1e3f96c3666245b3651ab8022738763b97e6a8 Mon Sep 17 00:00:00 2001 From: "xypron.glpk@gmx.de" Date: Sat, 15 Apr 2017 15:15:40 +0200 Subject: FPGA: drivers/fpga/ivm_core.c: incorrect printf The number of arguments for printf does not match the format string. The problem was indicated by cppcheck. Signed-off-by: Heinrich Schuchardt Reviewed-by: Tom Rini --- drivers/fpga/ivm_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/fpga/ivm_core.c b/drivers/fpga/ivm_core.c index 03aea625d58..78e9cc46ace 100644 --- a/drivers/fpga/ivm_core.c +++ b/drivers/fpga/ivm_core.c @@ -3142,7 +3142,7 @@ signed char ispVMProcessLVDS(unsigned short a_usLVDSCount) } #ifdef DEBUG - printf(");\n", a_usLVDSCount); + printf(");\n"); #endif /* DEBUG */ return 0; -- cgit v1.3.1 From 0e0de24b07b8314ea0cc247a89b722c2230e4b0a Mon Sep 17 00:00:00 2001 From: "xypron.glpk@gmx.de" Date: Sat, 15 Apr 2017 15:23:49 +0200 Subject: ddr: fsl: incorrect logical constraint in populate_memctl_options (pdimm[0].data_width >= 32) || (pdimm[0].data_width <= 40) is always true. We should use && here. The problem was indicated by cppcheck. Signed-off-by: Heinrich Schuchardt Reviewed-by: Tom Rini Reviewed-by: York Sun --- drivers/ddr/fsl/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c index d6a8fcb216a..cee97fe2323 100644 --- a/drivers/ddr/fsl/options.c +++ b/drivers/ddr/fsl/options.c @@ -916,7 +916,7 @@ unsigned int populate_memctl_options(const common_timing_params_t *common_dimm, if ((pdimm[0].data_width >= 64) && \ (pdimm[0].data_width <= 72)) popts->data_bus_width = 0; - else if ((pdimm[0].data_width >= 32) || \ + else if ((pdimm[0].data_width >= 32) && \ (pdimm[0].data_width <= 40)) popts->data_bus_width = 1; else { -- cgit v1.3.1 From 7a931b958e4f942b16d3f5d31dc4c0982fa186c8 Mon Sep 17 00:00:00 2001 From: "xypron.glpk@gmx.de" Date: Sat, 15 Apr 2017 15:31:53 +0200 Subject: fsl/sata: correctly identify failed malloc After allocating sata->cmd_hdr_tbl_offset we have to check this variable and not variable sata. The problem was indicated by cppcheck. Signed-off-by: Heinrich Schuchardt Reviewed-by: Tom Rini --- drivers/block/fsl_sata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/fsl_sata.c b/drivers/block/fsl_sata.c index e000ebff76f..31f7fab8b47 100644 --- a/drivers/block/fsl_sata.c +++ b/drivers/block/fsl_sata.c @@ -124,7 +124,7 @@ int init_sata(int dev) length = sizeof(struct cmd_hdr_tbl); align = SATA_HC_CMD_HDR_TBL_ALIGN; sata->cmd_hdr_tbl_offset = (void *)malloc(length + align); - if (!sata) { + if (!sata->cmd_hdr_tbl_offset) { printf("alloc the command header failed\n\r"); return -1; } -- cgit v1.3.1 From d1710561b0c4b68041d0f51e8fc5cfe3c2c15bb9 Mon Sep 17 00:00:00 2001 From: "xypron.glpk@gmx.de" Date: Sat, 15 Apr 2017 16:37:54 +0200 Subject: drivers/crypto/fsl: remove redundant logical contraint 'A || (!A && B)' is equivalent to 'A || B'. Let's reduce the complexity of the statement in start_jr0(). The problem was indicated by cppcheck. Signed-off-by: Heinrich Schuchardt Reviewed-by: York Sun Reviewed-by: Simon Glass --- drivers/crypto/fsl/jr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index 1b882291e4f..c33777fc7dd 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -47,8 +47,7 @@ static inline void start_jr0(uint8_t sec_idx) * VIRT_EN_INCL = 1 & VIRT_EN_POR = 0 & SEC_SCFGR_VIRT_EN = 1 */ if ((ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR) || - (!(ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR) && - (scfgr & SEC_SCFGR_VIRT_EN))) + (scfgr & SEC_SCFGR_VIRT_EN)) sec_out32(&sec->jrstartr, CONFIG_JRSTARTR_JR0); } else { /* VIRT_EN_INCL = 0 && VIRT_EN_POR_VALUE = 1 */ -- cgit v1.3.1 From 4d43d065db3262f9a9918ba72457bf36dfb8e0bb Mon Sep 17 00:00:00 2001 From: Mylène Josserand Date: Sun, 2 Apr 2017 12:59:03 +0200 Subject: sunxi: Move SUNXI_GMAC to Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the SUNXI_GMAC config option to Kconfig, remove it from SYS_EXTRA_OPTIONS and rename it into SUN7I_GMAC. Signed-off-by: Mylène Josserand Signed-off-by: Maxime Ripard --- configs/A20-OLinuXino-Lime2_defconfig | 3 ++- configs/A20-OLinuXino-Lime_defconfig | 3 ++- configs/A20-OLinuXino_MICRO_defconfig | 3 ++- configs/A20-Olimex-SOM-EVB_defconfig | 3 ++- configs/Bananapi_defconfig | 3 ++- configs/Bananapro_defconfig | 3 ++- configs/CSQ_CS908_defconfig | 2 +- configs/Colombus_defconfig | 3 ++- configs/Cubieboard2_defconfig | 3 ++- configs/Cubietruck_defconfig | 3 ++- configs/Hummingbird_A31_defconfig | 3 ++- configs/Itead_Ibox_A20_defconfig | 3 ++- configs/Lamobo_R1_defconfig | 3 ++- configs/Linksprite_pcDuino3_Nano_defconfig | 3 ++- configs/Linksprite_pcDuino3_defconfig | 3 ++- configs/Mele_A1000G_quad_defconfig | 2 +- configs/Mele_I7_defconfig | 2 +- configs/Mele_M3_defconfig | 2 +- configs/Mele_M5_defconfig | 2 +- configs/Mele_M9_defconfig | 2 +- configs/Orangepi_defconfig | 3 ++- configs/Orangepi_mini_defconfig | 3 ++- configs/Sinlinx_SinA31s_defconfig | 2 +- configs/Sinovoip_BPI_M2_defconfig | 3 ++- configs/Wits_Pro_A20_DKT_defconfig | 3 ++- configs/i12-tvbox_defconfig | 3 ++- configs/icnova-a20-swac_defconfig | 3 ++- configs/mixtile_loftq_defconfig | 3 ++- drivers/net/Kconfig | 5 +++++ 29 files changed, 54 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig index 4c720b31095..8883cf182da 100644 --- a/configs/A20-OLinuXino-Lime2_defconfig +++ b/configs/A20-OLinuXino-Lime2_defconfig @@ -8,7 +8,7 @@ CONFIG_USB0_VBUS_DET="PH5" CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olinuxino-lime2" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,SATAPWR=SUNXI_GPC(3)" +CONFIG_SYS_EXTRA_OPTIONS="RGMII,SATAPWR=SUNXI_GPC(3)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -25,6 +25,7 @@ CONFIG_NET_ETHADDR_EEPROM=y CONFIG_NET_ETHADDR_EEPROM_I2C=y CONFIG_NET_ETHADDR_EEPROM_I2C_BUS=1 CONFIG_I2C1_ENABLE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO3_VOLT=2800 CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig index 564ae256a35..d83fc2b4031 100644 --- a/configs/A20-OLinuXino-Lime_defconfig +++ b/configs/A20-OLinuXino-Lime_defconfig @@ -6,7 +6,7 @@ CONFIG_MMC0_CD_PIN="PH1" CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olinuxino-lime" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,SATAPWR=SUNXI_GPC(3)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPC(3)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -20,6 +20,7 @@ CONFIG_NET_ETHADDR_EEPROM=y CONFIG_NET_ETHADDR_EEPROM_I2C=y CONFIG_NET_ETHADDR_EEPROM_I2C_BUS=1 CONFIG_I2C1_ENABLE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO3_VOLT=2800 CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig index 93be13b4077..c25556bdac7 100644 --- a/configs/A20-OLinuXino_MICRO_defconfig +++ b/configs/A20-OLinuXino_MICRO_defconfig @@ -9,7 +9,7 @@ CONFIG_VIDEO_VGA=y CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olinuxino-micro" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,SATAPWR=SUNXI_GPB(8)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPB(8)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -23,6 +23,7 @@ CONFIG_NET_ETHADDR_EEPROM=y CONFIG_NET_ETHADDR_EEPROM_I2C=y CONFIG_NET_ETHADDR_EEPROM_I2C_BUS=1 CONFIG_I2C1_ENABLE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO3_VOLT=2800 CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/configs/A20-Olimex-SOM-EVB_defconfig b/configs/A20-Olimex-SOM-EVB_defconfig index b835dc59b90..9cb30c0c58e 100644 --- a/configs/A20-Olimex-SOM-EVB_defconfig +++ b/configs/A20-Olimex-SOM-EVB_defconfig @@ -11,7 +11,7 @@ CONFIG_USB0_VBUS_DET="PH5" CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olimex-som-evb" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,SATAPWR=SUNXI_GPC(3)" +CONFIG_SYS_EXTRA_OPTIONS="RGMII,SATAPWR=SUNXI_GPC(3)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -21,6 +21,7 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO3_VOLT=2800 CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig index 059559d3937..c780d6383ce 100644 --- a/configs/Bananapi_defconfig +++ b/configs/Bananapi_defconfig @@ -7,7 +7,7 @@ CONFIG_GMAC_TX_DELAY=3 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapi" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23)" +CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPH(23)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -18,4 +18,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_NETCONSOLE=y CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig index 27b9e63e006..5dd3088d3da 100644 --- a/configs/Bananapro_defconfig +++ b/configs/Bananapro_defconfig @@ -9,7 +9,7 @@ CONFIG_GMAC_TX_DELAY=3 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapro" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23)" +CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPH(23)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -20,5 +20,6 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_NETCONSOLE=y CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO4_VOLT=2500 CONFIG_USB_EHCI_HCD=y diff --git a/configs/CSQ_CS908_defconfig b/configs/CSQ_CS908_defconfig index 953ec253c04..a6fcbf5ecf3 100644 --- a/configs/CSQ_CS908_defconfig +++ b/configs/CSQ_CS908_defconfig @@ -6,7 +6,6 @@ CONFIG_USB1_VBUS_PIN="" CONFIG_USB2_VBUS_PIN="" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31s-cs908" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -15,6 +14,7 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_AXP_DLDO1_VOLT=3300 CONFIG_USB_EHCI_HCD=y diff --git a/configs/Colombus_defconfig b/configs/Colombus_defconfig index ac283a2070b..1e7d4982c07 100644 --- a/configs/Colombus_defconfig +++ b/configs/Colombus_defconfig @@ -16,7 +16,7 @@ CONFIG_VIDEO_LCD_PANEL_I2C_SCL="PA24" CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804=y CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-colombus" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII" +CONFIG_SYS_EXTRA_OPTIONS="RGMII" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -25,5 +25,6 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_USB_EHCI_HCD=y diff --git a/configs/Cubieboard2_defconfig b/configs/Cubieboard2_defconfig index 690ba49cfc2..8968623ec51 100644 --- a/configs/Cubieboard2_defconfig +++ b/configs/Cubieboard2_defconfig @@ -6,7 +6,7 @@ CONFIG_MMC0_CD_PIN="PH1" CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-cubieboard2" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,SATAPWR=SUNXI_GPB(8)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPB(8)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -16,4 +16,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig index ca549bc298e..576ccc3a206 100644 --- a/configs/Cubietruck_defconfig +++ b/configs/Cubietruck_defconfig @@ -11,7 +11,7 @@ CONFIG_GMAC_TX_DELAY=1 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-cubietruck" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,SATAPWR=SUNXI_GPH(12)" +CONFIG_SYS_EXTRA_OPTIONS="RGMII,SATAPWR=SUNXI_GPH(12)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -24,6 +24,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y # CONFIG_SPL_PARTITION_UUIDS is not set CONFIG_DFU_RAM=y CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_MUSB_GADGET=y CONFIG_USB_GADGET=y diff --git a/configs/Hummingbird_A31_defconfig b/configs/Hummingbird_A31_defconfig index c1cbbc829a1..d5de5184563 100644 --- a/configs/Hummingbird_A31_defconfig +++ b/configs/Hummingbird_A31_defconfig @@ -8,7 +8,7 @@ CONFIG_VIDEO_VGA_VIA_LCD=y CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN="PH25" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-hummingbird" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII" +CONFIG_SYS_EXTRA_OPTIONS="RGMII" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -17,5 +17,6 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_USB_EHCI_HCD=y diff --git a/configs/Itead_Ibox_A20_defconfig b/configs/Itead_Ibox_A20_defconfig index c38d71f25aa..bba0c5973b8 100644 --- a/configs/Itead_Ibox_A20_defconfig +++ b/configs/Itead_Ibox_A20_defconfig @@ -6,7 +6,7 @@ CONFIG_MMC0_CD_PIN="PH1" CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-itead-ibox" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,SATAPWR=SUNXI_GPB(8)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPB(8)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -16,4 +16,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Lamobo_R1_defconfig b/configs/Lamobo_R1_defconfig index 92ae4e231d7..142ed183ebc 100644 --- a/configs/Lamobo_R1_defconfig +++ b/configs/Lamobo_R1_defconfig @@ -7,7 +7,7 @@ CONFIG_GMAC_TX_DELAY=4 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-lamobo-r1" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),SATAPWR=SUNXI_GPB(3)" +CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPH(23),SATAPWR=SUNXI_GPB(3)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -17,4 +17,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Linksprite_pcDuino3_Nano_defconfig b/configs/Linksprite_pcDuino3_Nano_defconfig index 9c2cf8129f9..dd84b6ec51a 100644 --- a/configs/Linksprite_pcDuino3_Nano_defconfig +++ b/configs/Linksprite_pcDuino3_Nano_defconfig @@ -8,7 +8,7 @@ CONFIG_GMAC_TX_DELAY=3 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3-nano" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,SATAPWR=SUNXI_GPH(2)" +CONFIG_SYS_EXTRA_OPTIONS="RGMII,SATAPWR=SUNXI_GPH(2)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -18,4 +18,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig index b245e7e0d78..8e8455eee45 100644 --- a/configs/Linksprite_pcDuino3_defconfig +++ b/configs/Linksprite_pcDuino3_defconfig @@ -6,7 +6,7 @@ CONFIG_DRAM_ZQ=122 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,SATAPWR=SUNXI_GPH(2)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPH(2)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -16,4 +16,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Mele_A1000G_quad_defconfig b/configs/Mele_A1000G_quad_defconfig index 8f038353752..5b1b5f5d7ce 100644 --- a/configs/Mele_A1000G_quad_defconfig +++ b/configs/Mele_A1000G_quad_defconfig @@ -7,7 +7,6 @@ CONFIG_USB1_VBUS_PIN="PC27" CONFIG_USB2_VBUS_PIN="" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-mele-a1000g-quad" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -16,6 +15,7 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_DCDC1_VOLT=3300 CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_AXP_DLDO1_VOLT=3300 diff --git a/configs/Mele_I7_defconfig b/configs/Mele_I7_defconfig index 572b5219ccf..b60969787c9 100644 --- a/configs/Mele_I7_defconfig +++ b/configs/Mele_I7_defconfig @@ -6,7 +6,6 @@ CONFIG_USB1_VBUS_PIN="PC27" CONFIG_USB2_VBUS_PIN="" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-i7" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -15,6 +14,7 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_DCDC1_VOLT=3300 CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_AXP_DLDO1_VOLT=3300 diff --git a/configs/Mele_M3_defconfig b/configs/Mele_M3_defconfig index dd1526954bf..08e8c2dbde7 100644 --- a/configs/Mele_M3_defconfig +++ b/configs/Mele_M3_defconfig @@ -8,7 +8,6 @@ CONFIG_VIDEO_VGA=y CONFIG_VIDEO_COMPOSITE=y CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-m3" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -18,4 +17,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Mele_M5_defconfig b/configs/Mele_M5_defconfig index 12e1d0cae44..4c377e3daf0 100644 --- a/configs/Mele_M5_defconfig +++ b/configs/Mele_M5_defconfig @@ -8,7 +8,6 @@ CONFIG_VIDEO_COMPOSITE=y CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-m5" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -18,4 +17,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Mele_M9_defconfig b/configs/Mele_M9_defconfig index a9dc159063c..dc7901f9afc 100644 --- a/configs/Mele_M9_defconfig +++ b/configs/Mele_M9_defconfig @@ -6,7 +6,6 @@ CONFIG_USB1_VBUS_PIN="PC27" CONFIG_USB2_VBUS_PIN="" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-m9" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -15,6 +14,7 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_DCDC1_VOLT=3300 CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_AXP_DLDO1_VOLT=3300 diff --git a/configs/Orangepi_defconfig b/configs/Orangepi_defconfig index 3c9f74f3b4c..43765c697e7 100644 --- a/configs/Orangepi_defconfig +++ b/configs/Orangepi_defconfig @@ -10,7 +10,7 @@ CONFIG_GMAC_TX_DELAY=3 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-orangepi" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23)" +CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPH(23)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -20,4 +20,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Orangepi_mini_defconfig b/configs/Orangepi_mini_defconfig index f1d413b4455..772c00f7d15 100644 --- a/configs/Orangepi_mini_defconfig +++ b/configs/Orangepi_mini_defconfig @@ -12,7 +12,7 @@ CONFIG_GMAC_TX_DELAY=3 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-orangepi-mini" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23)" +CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPH(23)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -22,4 +22,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Sinlinx_SinA31s_defconfig b/configs/Sinlinx_SinA31s_defconfig index 54c975a2b2b..7f815a32cbd 100644 --- a/configs/Sinlinx_SinA31s_defconfig +++ b/configs/Sinlinx_SinA31s_defconfig @@ -10,7 +10,6 @@ CONFIG_USB1_VBUS_PIN="" CONFIG_USB2_VBUS_PIN="" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31s-sina31s" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -19,5 +18,6 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_DLDO1_VOLT=3300 CONFIG_USB_EHCI_HCD=y diff --git a/configs/Sinovoip_BPI_M2_defconfig b/configs/Sinovoip_BPI_M2_defconfig index dbff2344bbe..d123fad96bd 100644 --- a/configs/Sinovoip_BPI_M2_defconfig +++ b/configs/Sinovoip_BPI_M2_defconfig @@ -6,7 +6,7 @@ CONFIG_USB1_VBUS_PIN="" CONFIG_USB2_VBUS_PIN="" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31s-sinovoip-bpi-m2" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII" +CONFIG_SYS_EXTRA_OPTIONS="RGMII" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -15,6 +15,7 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_AXP_ALDO2_VOLT=1800 CONFIG_AXP_DLDO1_VOLT=3000 diff --git a/configs/Wits_Pro_A20_DKT_defconfig b/configs/Wits_Pro_A20_DKT_defconfig index cd6e821958a..97fb699eca7 100644 --- a/configs/Wits_Pro_A20_DKT_defconfig +++ b/configs/Wits_Pro_A20_DKT_defconfig @@ -11,7 +11,7 @@ CONFIG_VIDEO_LCD_PANEL_LVDS=y CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-wits-pro-a20-dkt" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII" +CONFIG_SYS_EXTRA_OPTIONS="RGMII" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -21,4 +21,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/i12-tvbox_defconfig b/configs/i12-tvbox_defconfig index 9715bb9228e..d7dc703981b 100644 --- a/configs/i12-tvbox_defconfig +++ b/configs/i12-tvbox_defconfig @@ -5,7 +5,7 @@ CONFIG_DRAM_CLK=384 CONFIG_VIDEO_COMPOSITE=y CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-i12-tvbox" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,MACPWR=SUNXI_GPH(21)" +CONFIG_SYS_EXTRA_OPTIONS="MACPWR=SUNXI_GPH(21)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -15,4 +15,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/icnova-a20-swac_defconfig b/configs/icnova-a20-swac_defconfig index 30e75e3c710..569f2d9c86f 100644 --- a/configs/icnova-a20-swac_defconfig +++ b/configs/icnova-a20-swac_defconfig @@ -12,7 +12,7 @@ CONFIG_VIDEO_LCD_POWER="PH22" CONFIG_VIDEO_LCD_PANEL_LVDS=y CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-icnova-swac" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,CMD_BMP" +CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,CMD_BMP" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -23,4 +23,5 @@ CONFIG_CMD_UNZIP=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/mixtile_loftq_defconfig b/configs/mixtile_loftq_defconfig index ec6a4381ac2..2dd107596ab 100644 --- a/configs/mixtile_loftq_defconfig +++ b/configs/mixtile_loftq_defconfig @@ -7,7 +7,7 @@ CONFIG_USB1_VBUS_PIN="PH24" CONFIG_USB2_VBUS_PIN="" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-mixtile-loftq" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPA(21)" +CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPA(21)" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -16,5 +16,6 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_USB_EHCI_HCD=y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 8aa92790f4b..1ba844d2776 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -161,6 +161,11 @@ config RTL8169 This driver supports Realtek 8169 series gigabit ethernet family of PCI/PCIe chipsets/adapters. +config SUN7I_GMAC + bool "Enable Allwinner GMAC Ethernet support" + help + Enable the support for Sun7i GMAC Ethernet controller + config SUN8I_EMAC bool "Allwinner Sun8i Ethernet MAC support" depends on DM_ETH -- cgit v1.3.1 From abc3e4df59f54cf3dda42a35a75d617fe861f5fe Mon Sep 17 00:00:00 2001 From: Mylène Josserand Date: Sun, 2 Apr 2017 12:59:07 +0200 Subject: sunxi: Convert SUNXI_EMAC to Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the SUNXI_EMAC config to Kconfig. Remove it from SYS_EXTRA_OPTIONS from many sunxi defconfig and renamed it into SUN4I_EMAC to not confuse it with SUN8I_EMAC. Signed-off-by: Mylène Josserand Signed-off-by: Maxime Ripard --- configs/A10-OLinuXino-Lime_defconfig | 3 ++- configs/A10s-OLinuXino-M_defconfig | 2 +- configs/Cubieboard_defconfig | 3 ++- configs/Linksprite_pcDuino_defconfig | 2 +- configs/Marsboard_A10_defconfig | 2 +- configs/Mele_A1000_defconfig | 3 ++- configs/ba10_tv_box_defconfig | 2 +- configs/jesurun_q5_defconfig | 3 ++- drivers/net/Kconfig | 6 ++++++ 9 files changed, 18 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/configs/A10-OLinuXino-Lime_defconfig b/configs/A10-OLinuXino-Lime_defconfig index 6634139ab86..967a3d442be 100644 --- a/configs/A10-OLinuXino-Lime_defconfig +++ b/configs/A10-OLinuXino-Lime_defconfig @@ -8,7 +8,7 @@ CONFIG_MMC0_CD_PIN="PH1" CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-olinuxino-lime" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC,SATAPWR=SUNXI_GPC(3)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPC(3)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -21,6 +21,7 @@ CONFIG_I2C1_ENABLE=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_SUN4I_EMAC=y CONFIG_AXP_ALDO3_VOLT=2800 CONFIG_AXP_ALDO4_VOLT=2800 CONFIG_USB_EHCI_HCD=y diff --git a/configs/A10s-OLinuXino-M_defconfig b/configs/A10s-OLinuXino-M_defconfig index 9c2a354ff44..af6f5bc6f75 100644 --- a/configs/A10s-OLinuXino-M_defconfig +++ b/configs/A10s-OLinuXino-M_defconfig @@ -8,7 +8,6 @@ CONFIG_MMC_SUNXI_SLOT_EXTRA=1 CONFIG_USB1_VBUS_PIN="PB10" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a10s-olinuxino-micro" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -17,5 +16,6 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_SUN4I_EMAC=y CONFIG_AXP152_POWER=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Cubieboard_defconfig b/configs/Cubieboard_defconfig index e1d1f1f8bb0..78fd4a211bc 100644 --- a/configs/Cubieboard_defconfig +++ b/configs/Cubieboard_defconfig @@ -6,7 +6,7 @@ CONFIG_MMC0_CD_PIN="PH1" CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-cubieboard" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC,SATAPWR=SUNXI_GPB(8)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPB(8)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -15,4 +15,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_SUN4I_EMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Linksprite_pcDuino_defconfig b/configs/Linksprite_pcDuino_defconfig index 1d2ab19a0b1..e33a9c13a12 100644 --- a/configs/Linksprite_pcDuino_defconfig +++ b/configs/Linksprite_pcDuino_defconfig @@ -5,7 +5,6 @@ CONFIG_USB1_VBUS_PIN="" CONFIG_USB2_VBUS_PIN="" CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-pcduino" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -14,4 +13,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_SUN4I_EMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Marsboard_A10_defconfig b/configs/Marsboard_A10_defconfig index 34e78f1e8c6..6b8bd1ad205 100644 --- a/configs/Marsboard_A10_defconfig +++ b/configs/Marsboard_A10_defconfig @@ -4,7 +4,6 @@ CONFIG_MACH_SUN4I=y CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-marsboard" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -12,5 +11,6 @@ CONFIG_SPL=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_SUN4I_EMAC=y CONFIG_SUNXI_NO_PMIC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Mele_A1000_defconfig b/configs/Mele_A1000_defconfig index 4496688d3f1..4bd81a262cd 100644 --- a/configs/Mele_A1000_defconfig +++ b/configs/Mele_A1000_defconfig @@ -6,7 +6,7 @@ CONFIG_VIDEO_COMPOSITE=y CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-a1000" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC,MACPWR=SUNXI_GPH(15)" +CONFIG_SYS_EXTRA_OPTIONS="MACPWR=SUNXI_GPH(15)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -15,4 +15,5 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_SUN4I_EMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/ba10_tv_box_defconfig b/configs/ba10_tv_box_defconfig index ec711591514..ad066fdffa0 100644 --- a/configs/ba10_tv_box_defconfig +++ b/configs/ba10_tv_box_defconfig @@ -8,7 +8,6 @@ CONFIG_USB2_VBUS_PIN="PH12" CONFIG_VIDEO_COMPOSITE=y CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-ba10-tvbox" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -17,5 +16,6 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_SUN4I_EMAC=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_MUSB_HOST=y diff --git a/configs/jesurun_q5_defconfig b/configs/jesurun_q5_defconfig index a6bec12fd2e..608e523e4c0 100644 --- a/configs/jesurun_q5_defconfig +++ b/configs/jesurun_q5_defconfig @@ -6,7 +6,7 @@ CONFIG_USB0_VBUS_PIN="PB9" CONFIG_VIDEO_COMPOSITE=y CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-jesurun-q5" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC,MACPWR=SUNXI_GPH(19)" +CONFIG_SYS_EXTRA_OPTIONS="MACPWR=SUNXI_GPH(19)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -15,5 +15,6 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_DOS_PARTITION is not set # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set +CONFIG_SUN4I_EMAC=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_MUSB_HOST=y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 1ba844d2776..6126d10c39b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -166,6 +166,12 @@ config SUN7I_GMAC help Enable the support for Sun7i GMAC Ethernet controller +config SUN4I_EMAC + bool "Allwinner Sun4i Ethernet MAC support" + depends on DM_ETH + help + This driver supports the Allwinner based SUN4I Ethernet MAC. + config SUN8I_EMAC bool "Allwinner Sun8i Ethernet MAC support" depends on DM_ETH -- cgit v1.3.1 From 751b0be0a1753bbc2f43c1d32e704bac9412d5af Mon Sep 17 00:00:00 2001 From: Mylène Josserand Date: Sun, 2 Apr 2017 12:59:08 +0200 Subject: sunxi: Convert CONFIG_RGMII to Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert CONFIG_RGMII to Kconfig. Thanks to that, it is possible to update defconfig files of SYS_EXTRA_OPTIONS accordingly and remove it when it is possible. Signed-off-by: Mylène Josserand Signed-off-by: Maxime Ripard --- configs/A20-OLinuXino-Lime2_defconfig | 3 ++- configs/A20-Olimex-SOM-EVB_defconfig | 3 ++- configs/Bananapi_defconfig | 3 ++- configs/Bananapro_defconfig | 3 ++- configs/Colombus_defconfig | 2 +- configs/Cubietruck_defconfig | 3 ++- configs/Hummingbird_A31_defconfig | 2 +- configs/Lamobo_R1_defconfig | 3 ++- configs/Linksprite_pcDuino3_Nano_defconfig | 3 ++- configs/Orangepi_defconfig | 3 ++- configs/Orangepi_mini_defconfig | 3 ++- configs/Sinovoip_BPI_M2_defconfig | 2 +- configs/Wits_Pro_A20_DKT_defconfig | 2 +- configs/mixtile_loftq_defconfig | 3 ++- drivers/net/Kconfig | 6 ++++++ 15 files changed, 30 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig index 8883cf182da..0c9c7943f98 100644 --- a/configs/A20-OLinuXino-Lime2_defconfig +++ b/configs/A20-OLinuXino-Lime2_defconfig @@ -8,7 +8,7 @@ CONFIG_USB0_VBUS_DET="PH5" CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olinuxino-lime2" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII,SATAPWR=SUNXI_GPC(3)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPC(3)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -25,6 +25,7 @@ CONFIG_NET_ETHADDR_EEPROM=y CONFIG_NET_ETHADDR_EEPROM_I2C=y CONFIG_NET_ETHADDR_EEPROM_I2C_BUS=1 CONFIG_I2C1_ENABLE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO3_VOLT=2800 CONFIG_AXP_ALDO4_VOLT=2800 diff --git a/configs/A20-Olimex-SOM-EVB_defconfig b/configs/A20-Olimex-SOM-EVB_defconfig index 9cb30c0c58e..ce658ca984f 100644 --- a/configs/A20-Olimex-SOM-EVB_defconfig +++ b/configs/A20-Olimex-SOM-EVB_defconfig @@ -11,7 +11,7 @@ CONFIG_USB0_VBUS_DET="PH5" CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olimex-som-evb" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII,SATAPWR=SUNXI_GPC(3)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPC(3)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -21,6 +21,7 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO3_VOLT=2800 CONFIG_AXP_ALDO4_VOLT=2800 diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig index c780d6383ce..29e7f700f2e 100644 --- a/configs/Bananapi_defconfig +++ b/configs/Bananapi_defconfig @@ -7,7 +7,7 @@ CONFIG_GMAC_TX_DELAY=3 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapi" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPH(23)" +CONFIG_SYS_EXTRA_OPTIONS="MACPWR=SUNXI_GPH(23)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -18,5 +18,6 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_NETCONSOLE=y CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig index 5dd3088d3da..bb25dec2a98 100644 --- a/configs/Bananapro_defconfig +++ b/configs/Bananapro_defconfig @@ -9,7 +9,7 @@ CONFIG_GMAC_TX_DELAY=3 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapro" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPH(23)" +CONFIG_SYS_EXTRA_OPTIONS="MACPWR=SUNXI_GPH(23)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -20,6 +20,7 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_NETCONSOLE=y CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO4_VOLT=2500 CONFIG_USB_EHCI_HCD=y diff --git a/configs/Colombus_defconfig b/configs/Colombus_defconfig index 1e7d4982c07..1359281ff41 100644 --- a/configs/Colombus_defconfig +++ b/configs/Colombus_defconfig @@ -16,7 +16,6 @@ CONFIG_VIDEO_LCD_PANEL_I2C_SCL="PA24" CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804=y CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-colombus" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -25,6 +24,7 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_USB_EHCI_HCD=y diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig index 576ccc3a206..9f2e994f71b 100644 --- a/configs/Cubietruck_defconfig +++ b/configs/Cubietruck_defconfig @@ -11,7 +11,7 @@ CONFIG_GMAC_TX_DELAY=1 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-cubietruck" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII,SATAPWR=SUNXI_GPH(12)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPH(12)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -24,6 +24,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y # CONFIG_SPL_PARTITION_UUIDS is not set CONFIG_DFU_RAM=y CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_MUSB_GADGET=y diff --git a/configs/Hummingbird_A31_defconfig b/configs/Hummingbird_A31_defconfig index d5de5184563..6f9b1032075 100644 --- a/configs/Hummingbird_A31_defconfig +++ b/configs/Hummingbird_A31_defconfig @@ -8,7 +8,6 @@ CONFIG_VIDEO_VGA_VIA_LCD=y CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN="PH25" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-hummingbird" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -17,6 +16,7 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_USB_EHCI_HCD=y diff --git a/configs/Lamobo_R1_defconfig b/configs/Lamobo_R1_defconfig index 142ed183ebc..61a9316e7ad 100644 --- a/configs/Lamobo_R1_defconfig +++ b/configs/Lamobo_R1_defconfig @@ -7,7 +7,7 @@ CONFIG_GMAC_TX_DELAY=4 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-lamobo-r1" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPH(23),SATAPWR=SUNXI_GPB(3)" +CONFIG_SYS_EXTRA_OPTIONS="MACPWR=SUNXI_GPH(23),SATAPWR=SUNXI_GPB(3)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -17,5 +17,6 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Linksprite_pcDuino3_Nano_defconfig b/configs/Linksprite_pcDuino3_Nano_defconfig index dd84b6ec51a..38adfc0f28f 100644 --- a/configs/Linksprite_pcDuino3_Nano_defconfig +++ b/configs/Linksprite_pcDuino3_Nano_defconfig @@ -8,7 +8,7 @@ CONFIG_GMAC_TX_DELAY=3 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3-nano" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII,SATAPWR=SUNXI_GPH(2)" +CONFIG_SYS_EXTRA_OPTIONS="SATAPWR=SUNXI_GPH(2)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -18,5 +18,6 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Orangepi_defconfig b/configs/Orangepi_defconfig index 43765c697e7..e9781554f85 100644 --- a/configs/Orangepi_defconfig +++ b/configs/Orangepi_defconfig @@ -10,7 +10,7 @@ CONFIG_GMAC_TX_DELAY=3 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-orangepi" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPH(23)" +CONFIG_SYS_EXTRA_OPTIONS="MACPWR=SUNXI_GPH(23)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -20,5 +20,6 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Orangepi_mini_defconfig b/configs/Orangepi_mini_defconfig index 772c00f7d15..508b4aca765 100644 --- a/configs/Orangepi_mini_defconfig +++ b/configs/Orangepi_mini_defconfig @@ -12,7 +12,7 @@ CONFIG_GMAC_TX_DELAY=3 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-orangepi-mini" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPH(23)" +CONFIG_SYS_EXTRA_OPTIONS="MACPWR=SUNXI_GPH(23)" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -22,5 +22,6 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/Sinovoip_BPI_M2_defconfig b/configs/Sinovoip_BPI_M2_defconfig index d123fad96bd..a2cadbc2715 100644 --- a/configs/Sinovoip_BPI_M2_defconfig +++ b/configs/Sinovoip_BPI_M2_defconfig @@ -6,7 +6,6 @@ CONFIG_USB1_VBUS_PIN="" CONFIG_USB2_VBUS_PIN="" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31s-sinovoip-bpi-m2" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -15,6 +14,7 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_AXP_ALDO2_VOLT=1800 diff --git a/configs/Wits_Pro_A20_DKT_defconfig b/configs/Wits_Pro_A20_DKT_defconfig index 97fb699eca7..8658ef6b4c9 100644 --- a/configs/Wits_Pro_A20_DKT_defconfig +++ b/configs/Wits_Pro_A20_DKT_defconfig @@ -11,7 +11,6 @@ CONFIG_VIDEO_LCD_PANEL_LVDS=y CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-wits-pro-a20-dkt" CONFIG_AHCI=y # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set @@ -21,5 +20,6 @@ CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/mixtile_loftq_defconfig b/configs/mixtile_loftq_defconfig index 2dd107596ab..591f48169df 100644 --- a/configs/mixtile_loftq_defconfig +++ b/configs/mixtile_loftq_defconfig @@ -7,7 +7,7 @@ CONFIG_USB1_VBUS_PIN="PH24" CONFIG_USB2_VBUS_PIN="" CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-mixtile-loftq" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="RGMII,MACPWR=SUNXI_GPA(21)" +CONFIG_SYS_EXTRA_OPTIONS="MACPWR=SUNXI_GPA(21)" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -16,6 +16,7 @@ CONFIG_SPL=y # CONFIG_SPL_ISO_PARTITION is not set # CONFIG_SPL_EFI_PARTITION is not set CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y CONFIG_SUN7I_GMAC=y CONFIG_AXP_ALDO1_VOLT=3300 CONFIG_USB_EHCI_HCD=y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6126d10c39b..9cd0d94cbdc 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -149,6 +149,12 @@ config PCH_GBE This MAC is present in Intel Platform Controller Hub EG20T. It supports 10/100/1000 Mbps operation. +config RGMII + bool "Enable RGMII" + help + Enable the support of the Reduced Gigabit Media-Independent + Interface (RGMII). + config RTL8139 bool "Realtek 8139 series Ethernet controller driver" help -- cgit v1.3.1 From 7095f864186350dd5773a0bda2df19a1fa8d0aeb Mon Sep 17 00:00:00 2001 From: Mylène Josserand Date: Sun, 2 Apr 2017 12:59:11 +0200 Subject: sunxi: Convert CONS_INDEX to Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the CONS_INDEX configuration to Kconfig. Update sunxi's defconfigs to remove SYS_EXTRA_OPTIONS variable not needed anymore. Default value is 1 except for sun5i (equals 2) and sun8i (equals 5). Signed-off-by: Mylène Josserand [Maxime: Added a depends on ARCH_SUNXI to avoid build breakages] Signed-off-by: Maxime Ripard --- configs/A13-OLinuXinoM_defconfig | 1 - configs/A13-OLinuXino_defconfig | 1 - configs/Ampe_A76_defconfig | 1 - configs/CHIP_defconfig | 1 - configs/CHIP_pro_defconfig | 2 +- configs/Empire_electronix_d709_defconfig | 1 - configs/Empire_electronix_m712_defconfig | 1 - configs/difrnce_dit4350_defconfig | 1 - configs/ga10h_v1_1_defconfig | 1 - configs/gt90h_v4_defconfig | 1 - configs/iNet_D978_rev2_defconfig | 1 - configs/inet86dz_defconfig | 1 - configs/inet98v_rev2_defconfig | 1 - configs/polaroid_mid2407pxe03_defconfig | 1 - configs/polaroid_mid2809pxe04_defconfig | 1 - configs/q8_a13_tablet_defconfig | 1 - configs/q8_a23_tablet_800x480_defconfig | 1 - configs/q8_a33_tablet_1024x600_defconfig | 1 - configs/q8_a33_tablet_800x480_defconfig | 1 - configs/sun8i_a23_evb_defconfig | 1 - drivers/serial/Kconfig | 11 +++++++++++ include/configs/sunxi-common.h | 4 ---- 22 files changed, 12 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/configs/A13-OLinuXinoM_defconfig b/configs/A13-OLinuXinoM_defconfig index 264135b271b..530a60edbb5 100644 --- a/configs/A13-OLinuXinoM_defconfig +++ b/configs/A13-OLinuXinoM_defconfig @@ -12,7 +12,6 @@ CONFIG_VIDEO_LCD_POWER="PB10" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino-micro" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig index 705fe5d212a..15c6879c71c 100644 --- a/configs/A13-OLinuXino_defconfig +++ b/configs/A13-OLinuXino_defconfig @@ -14,7 +14,6 @@ CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set diff --git a/configs/Ampe_A76_defconfig b/configs/Ampe_A76_defconfig index 20272a6c356..f3f599d6b11 100644 --- a/configs/Ampe_A76_defconfig +++ b/configs/Ampe_A76_defconfig @@ -14,7 +14,6 @@ CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-ampe-a76" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set diff --git a/configs/CHIP_defconfig b/configs/CHIP_defconfig index 3f993844b1c..3e8bc1631d5 100644 --- a/configs/CHIP_defconfig +++ b/configs/CHIP_defconfig @@ -6,7 +6,6 @@ CONFIG_DRAM_TIMINGS_DDR3_800E_1066G_1333J=y CONFIG_USB0_VBUS_PIN="PB10" CONFIG_VIDEO_COMPOSITE=y CONFIG_DEFAULT_DEVICE_TREE="sun5i-r8-chip" -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set diff --git a/configs/CHIP_pro_defconfig b/configs/CHIP_pro_defconfig index df43e5a12d0..78fdb0e7d8e 100644 --- a/configs/CHIP_pro_defconfig +++ b/configs/CHIP_pro_defconfig @@ -7,7 +7,7 @@ CONFIG_MACH_SUN5I=y CONFIG_DRAM_TIMINGS_DDR3_800E_1066G_1333J=y CONFIG_USB0_VBUS_PIN="PB10" CONFIG_DEFAULT_DEVICE_TREE="sun5i-gr8-chip-pro" -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,SYS_NAND_BLOCK_SIZE=0x40000,SYS_NAND_PAGE_SIZE=4096,SYS_NAND_OOBSIZE=256" +CONFIG_SYS_EXTRA_OPTIONS="SYS_NAND_BLOCK_SIZE=0x40000,SYS_NAND_PAGE_SIZE=4096,SYS_NAND_OOBSIZE=256" CONFIG_ENV_IS_IN_UBI=y CONFIG_ENV_UBI_PART="UBI" CONFIG_ENV_UBI_VOLUME="uboot-env" diff --git a/configs/Empire_electronix_d709_defconfig b/configs/Empire_electronix_d709_defconfig index 6460814db33..032056bb38c 100644 --- a/configs/Empire_electronix_d709_defconfig +++ b/configs/Empire_electronix_d709_defconfig @@ -15,7 +15,6 @@ CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-empire-electronix-d709" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set diff --git a/configs/Empire_electronix_m712_defconfig b/configs/Empire_electronix_m712_defconfig index 48e26a5db14..8437da3b2da 100644 --- a/configs/Empire_electronix_m712_defconfig +++ b/configs/Empire_electronix_m712_defconfig @@ -14,7 +14,6 @@ CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-empire-electronix-m712" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set diff --git a/configs/difrnce_dit4350_defconfig b/configs/difrnce_dit4350_defconfig index ea07b38a68c..629507e741f 100644 --- a/configs/difrnce_dit4350_defconfig +++ b/configs/difrnce_dit4350_defconfig @@ -14,7 +14,6 @@ CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-difrnce-dit4350" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set diff --git a/configs/ga10h_v1_1_defconfig b/configs/ga10h_v1_1_defconfig index 358a13996a7..8e1c9f79a87 100644 --- a/configs/ga10h_v1_1_defconfig +++ b/configs/ga10h_v1_1_defconfig @@ -16,7 +16,6 @@ CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_VIDEO_LCD_PANEL_LVDS=y CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-ga10h-v1.1" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/gt90h_v4_defconfig b/configs/gt90h_v4_defconfig index d7c2bb7b6ef..8f6469de613 100644 --- a/configs/gt90h_v4_defconfig +++ b/configs/gt90h_v4_defconfig @@ -15,7 +15,6 @@ CONFIG_VIDEO_LCD_BL_EN="PH6" CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-gt90h-v4" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/iNet_D978_rev2_defconfig b/configs/iNet_D978_rev2_defconfig index b2febab2dbd..62e4f1b3636 100644 --- a/configs/iNet_D978_rev2_defconfig +++ b/configs/iNet_D978_rev2_defconfig @@ -16,7 +16,6 @@ CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_VIDEO_LCD_PANEL_LVDS=y CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-inet-d978-rev2" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/inet86dz_defconfig b/configs/inet86dz_defconfig index c7753b3a723..7940d971b76 100644 --- a/configs/inet86dz_defconfig +++ b/configs/inet86dz_defconfig @@ -15,7 +15,6 @@ CONFIG_VIDEO_LCD_BL_EN="PH6" CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-inet86dz" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/inet98v_rev2_defconfig b/configs/inet98v_rev2_defconfig index 329c858590a..2afe3be5126 100644 --- a/configs/inet98v_rev2_defconfig +++ b/configs/inet98v_rev2_defconfig @@ -14,7 +14,6 @@ CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-inet-98v-rev2" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set diff --git a/configs/polaroid_mid2407pxe03_defconfig b/configs/polaroid_mid2407pxe03_defconfig index 3beba97cdd5..d48a50701bb 100644 --- a/configs/polaroid_mid2407pxe03_defconfig +++ b/configs/polaroid_mid2407pxe03_defconfig @@ -15,7 +15,6 @@ CONFIG_VIDEO_LCD_BL_EN="PH6" CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-polaroid-mid2407pxe03" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/polaroid_mid2809pxe04_defconfig b/configs/polaroid_mid2809pxe04_defconfig index bbf2819252c..72fe096e632 100644 --- a/configs/polaroid_mid2809pxe04_defconfig +++ b/configs/polaroid_mid2809pxe04_defconfig @@ -15,7 +15,6 @@ CONFIG_VIDEO_LCD_BL_EN="PH6" CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-polaroid-mid2809pxe04" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/q8_a13_tablet_defconfig b/configs/q8_a13_tablet_defconfig index fad22f5ea7d..5115739b8d1 100644 --- a/configs/q8_a13_tablet_defconfig +++ b/configs/q8_a13_tablet_defconfig @@ -14,7 +14,6 @@ CONFIG_VIDEO_LCD_BL_EN="AXP0-1" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-q8-tablet" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2" CONFIG_SPL=y CONFIG_SPL_I2C_SUPPORT=y # CONFIG_CMD_IMLS is not set diff --git a/configs/q8_a23_tablet_800x480_defconfig b/configs/q8_a23_tablet_800x480_defconfig index 5ad67d7bee4..1762fe48d63 100644 --- a/configs/q8_a23_tablet_800x480_defconfig +++ b/configs/q8_a23_tablet_800x480_defconfig @@ -15,7 +15,6 @@ CONFIG_VIDEO_LCD_BL_EN="PH6" CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-q8-tablet" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/q8_a33_tablet_1024x600_defconfig b/configs/q8_a33_tablet_1024x600_defconfig index 0e3bc133ea7..d42b597db69 100644 --- a/configs/q8_a33_tablet_1024x600_defconfig +++ b/configs/q8_a33_tablet_1024x600_defconfig @@ -15,7 +15,6 @@ CONFIG_VIDEO_LCD_BL_EN="PH6" CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-q8-tablet" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/q8_a33_tablet_800x480_defconfig b/configs/q8_a33_tablet_800x480_defconfig index b5b7782a60e..5b6dfe0d870 100644 --- a/configs/q8_a33_tablet_800x480_defconfig +++ b/configs/q8_a33_tablet_800x480_defconfig @@ -15,7 +15,6 @@ CONFIG_VIDEO_LCD_BL_EN="PH6" CONFIG_VIDEO_LCD_BL_PWM="PH0" CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-q8-tablet" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/configs/sun8i_a23_evb_defconfig b/configs/sun8i_a23_evb_defconfig index 296df00043d..49ba4314520 100644 --- a/configs/sun8i_a23_evb_defconfig +++ b/configs/sun8i_a23_evb_defconfig @@ -8,7 +8,6 @@ CONFIG_USB0_VBUS_DET="axp_vbus_detect" CONFIG_USB1_VBUS_PIN="PH7" CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-evb" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index c0ec2ec2e4d..a753367ee14 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -44,6 +44,17 @@ config SPL_SERIAL_PRESENT This option enables the full UART in SPL, so if is it disabled, the full UART driver will be omitted, thus saving space. +config CONS_INDEX + int "UART used for console" + depends on ARCH_SUNXI + default 2 if MACH_SUN5I + default 5 if MACH_SUN8I + default 1 + help + Configures the console index. + For Allwinner SoC., default values are 2 for SUN5I and 5 for SUN8I. + Otherwise, the index equals 1. + config DM_SERIAL bool "Enable Driver Model for serial drivers" depends on DM diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 1d475b10ddf..b32d220befb 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -231,10 +231,6 @@ extern int soft_i2c_gpio_scl; defined CONFIG_SY8106A_POWER #endif -#ifndef CONFIG_CONS_INDEX -#define CONFIG_CONS_INDEX 1 /* UART0 */ -#endif - #ifdef CONFIG_REQUIRE_SERIAL_CONSOLE #if CONFIG_CONS_INDEX == 1 #ifdef CONFIG_MACH_SUN9I -- cgit v1.3.1 From 409677ec1706c1374f9ce5e1833ae425dd0a9602 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 30 Nov 2016 15:30:30 +0800 Subject: sunxi: Enable AXP221s in I2C mode with the R40 SoC The R40 SoC uses the AXP221s in I2C mode to supply power. Some regulator's common usages have changed, and also the recommended voltage for existing usages have changed. Update the defaults to match. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard --- arch/arm/mach-sunxi/pmic_bus.c | 7 +++++++ board/sunxi/Kconfig | 2 +- drivers/power/Kconfig | 16 ++++++++++------ 3 files changed, 18 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c index 7c57f02792b..f917c3e070a 100644 --- a/arch/arm/mach-sunxi/pmic_bus.c +++ b/arch/arm/mach-sunxi/pmic_bus.c @@ -41,6 +41,9 @@ int pmic_bus_init(void) p2wi_init(); ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR, AXP221_INIT_DATA); +# elif defined CONFIG_MACH_SUN8I_R40 + /* Nothing. R40 uses the AXP221s in I2C mode */ + ret = 0; # else ret = rsb_init(); if (ret) @@ -65,6 +68,8 @@ int pmic_bus_read(u8 reg, u8 *data) #elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER # ifdef CONFIG_MACH_SUN6I return p2wi_read(reg, data); +# elif defined CONFIG_MACH_SUN8I_R40 + return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1); # else return rsb_read(AXP223_RUNTIME_ADDR, reg, data); # endif @@ -80,6 +85,8 @@ int pmic_bus_write(u8 reg, u8 data) #elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER # ifdef CONFIG_MACH_SUN6I return p2wi_write(reg, data); +# elif defined CONFIG_MACH_SUN8I_R40 + return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1); # else return rsb_write(AXP223_RUNTIME_ADDR, reg, data); # endif diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 3df70773132..f40b8ff57d2 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -473,7 +473,7 @@ config USB3_VBUS_PIN config I2C0_ENABLE bool "Enable I2C/TWI controller 0" - default y if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I + default y if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUN8I_R40 default n if MACH_SUN6I || MACH_SUN8I select CMD_I2C ---help--- diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 64e5bc2f74b..911ecb1144a 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -10,7 +10,7 @@ choice prompt "Select Sunxi PMIC Variant" depends on ARCH_SUNXI default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I - default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 + default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_R40 default AXP818_POWER if MACH_SUN8I_A83T default SUNXI_NO_PMIC if MACH_SUNXI_H3_H5 || MACH_SUN50I @@ -37,7 +37,7 @@ config AXP209_POWER config AXP221_POWER bool "axp221 / axp223 pmic support" - depends on MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 + depends on MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_R40 select CMD_POWEROFF ---help--- Select this to enable support for the axp221/axp223 pmic found on most @@ -70,7 +70,7 @@ endchoice config AXP_DCDC1_VOLT int "axp pmic dcdc1 voltage" depends on AXP221_POWER || AXP809_POWER || AXP818_POWER - default 3300 if AXP818_POWER + default 3300 if AXP818_POWER || MACH_SUN8I_R40 default 3000 if MACH_SUN6I || MACH_SUN8I || MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic dcdc1 at, set to 0 to @@ -97,6 +97,7 @@ config AXP_DCDC2_VOLT On A23/A33 boards dcdc2 is used for VDD-SYS and should be 1.1V. On A80 boards dcdc2 powers the GPU and can be left off. On A83T boards dcdc2 is used for VDD-CPUA(cluster 0) and should be 0.9V. + On R40 boards dcdc2 is VDD-CPU and should be 1.1V config AXP_DCDC3_VOLT int "axp pmic dcdc3 voltage" @@ -104,6 +105,7 @@ config AXP_DCDC3_VOLT default 900 if AXP809_POWER || AXP818_POWER default 1500 if AXP152_POWER default 1250 if AXP209_POWER + default 1100 if MACH_SUN8I_R40 default 1200 if MACH_SUN6I || MACH_SUN8I ---help--- Set the voltage (mV) to program the axp pmic dcdc3 at, set to 0 to @@ -114,6 +116,7 @@ config AXP_DCDC3_VOLT On A23 / A31 / A33 boards dcdc3 is VDD-CPU and should be 1.2V. On A80 boards dcdc3 is used for VDD-CPUA(cluster 0) and should be 0.9V. On A83T boards dcdc3 is used for VDD-CPUB(cluster 1) and should be 0.9V. + On R40 boards dcdc3 is VDD-SYS and VDD-GPU and should be 1.1V. config AXP_DCDC4_VOLT int "axp pmic dcdc4 voltage" @@ -138,13 +141,13 @@ config AXP_DCDC5_VOLT ---help--- Set the voltage (mV) to program the axp pmic dcdc5 at, set to 0 to disable dcdc5. - On A23 / A31 / A33 / A80 / A83T boards dcdc5 is VCC-DRAM and + On A23 / A31 / A33 / A80 / A83T / R40 boards dcdc5 is VCC-DRAM and should be 1.5V, 1.35V if DDR3L is used. config AXP_ALDO1_VOLT int "axp pmic (a)ldo1 voltage" depends on AXP221_POWER || AXP809_POWER || AXP818_POWER - default 0 if MACH_SUN6I + default 0 if MACH_SUN6I || MACH_SUN8I_R40 default 1800 if MACH_SUN8I_A83T default 3000 if MACH_SUN8I || MACH_SUN9I ---help--- @@ -183,7 +186,8 @@ config AXP_ALDO3_VOLT Set the voltage (mV) to program the axp pmic aldo3 at, set to 0 to disable aldo3. On A10(s) / A13 / A20 boards aldo3 should be 2.8V. - On A23 / A31 / A33 boards aldo3 is VCC-PLL and AVCC and should be 3.0V. + On A23 / A31 / A33 / R40 boards aldo3 is VCC-PLL and AVCC and should + be 3.0V. On A80 boards aldo3 is normally not used. On A83T / H8 boards aldo3 is AVCC, VCC-PL, and VCC-LED, and should be 3.0V. -- cgit v1.3.1 From 33559ffe5bc0ea10ae9956a0ac3fbd1cc30d23b8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 30 Nov 2016 17:23:52 +0800 Subject: gpio: sunxi: Add compatible string for R40 PIO The PIO on the R40 SoC is mostly compatible with the A20. Only a few pin functions for mmc2 were added to the PC pingroup, to support 8 bit eMMCs. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard --- drivers/gpio/sunxi_gpio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 8d2bb18504a..3f40e838300 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -352,6 +352,7 @@ static const struct udevice_id sunxi_gpio_ids[] = { ID("allwinner,sun8i-a33-pinctrl", a_all), ID("allwinner,sun8i-a83t-pinctrl", a_all), ID("allwinner,sun8i-h3-pinctrl", a_all), + ID("allwinner,sun8i-r40-pinctrl", a_all), ID("allwinner,sun9i-a80-pinctrl", a_all), ID("allwinner,sun6i-a31-r-pinctrl", l_2), ID("allwinner,sun8i-a23-r-pinctrl", l_1), -- cgit v1.3.1 From 5e023e7eb3c4dca6ddc2d7dbd862b5e781a6fbec Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Mon, 27 Mar 2017 19:22:29 +0200 Subject: sunxi: video: Split out TCON code TCON unit has similar layout and functionality also on newer SoCs. This commit splits out TCON code for easier reuse later. Signed-off-by: Jernej Skrabec Acked-by: Maxime Ripard Signed-off-by: Maxime Ripard --- arch/arm/include/asm/arch-sunxi/display.h | 103 -- arch/arm/include/asm/arch-sunxi/lcdc.h | 128 +++ drivers/video/Makefile | 2 +- drivers/video/sunxi/Makefile | 8 + drivers/video/sunxi/lcdc.c | 207 ++++ drivers/video/sunxi/sunxi_display.c | 1436 ++++++++++++++++++++++++++ drivers/video/sunxi_display.c | 1599 ----------------------------- 7 files changed, 1780 insertions(+), 1703 deletions(-) create mode 100644 arch/arm/include/asm/arch-sunxi/lcdc.h create mode 100644 drivers/video/sunxi/Makefile create mode 100644 drivers/video/sunxi/lcdc.c create mode 100644 drivers/video/sunxi/sunxi_display.c delete mode 100644 drivers/video/sunxi_display.c (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h index b64f310b8bf..93803addfbe 100644 --- a/arch/arm/include/asm/arch-sunxi/display.h +++ b/arch/arm/include/asm/arch-sunxi/display.h @@ -157,52 +157,6 @@ struct sunxi_de_be_reg { u32 output_color_coef[12]; /* 0x9d0 */ }; -struct sunxi_lcdc_reg { - u32 ctrl; /* 0x00 */ - u32 int0; /* 0x04 */ - u32 int1; /* 0x08 */ - u8 res0[0x04]; /* 0x0c */ - u32 tcon0_frm_ctrl; /* 0x10 */ - u32 tcon0_frm_seed[6]; /* 0x14 */ - u32 tcon0_frm_table[4]; /* 0x2c */ - u8 res1[4]; /* 0x3c */ - u32 tcon0_ctrl; /* 0x40 */ - u32 tcon0_dclk; /* 0x44 */ - u32 tcon0_timing_active; /* 0x48 */ - u32 tcon0_timing_h; /* 0x4c */ - u32 tcon0_timing_v; /* 0x50 */ - u32 tcon0_timing_sync; /* 0x54 */ - u32 tcon0_hv_intf; /* 0x58 */ - u8 res2[0x04]; /* 0x5c */ - u32 tcon0_cpu_intf; /* 0x60 */ - u32 tcon0_cpu_wr_dat; /* 0x64 */ - u32 tcon0_cpu_rd_dat0; /* 0x68 */ - u32 tcon0_cpu_rd_dat1; /* 0x6c */ - u32 tcon0_ttl_timing0; /* 0x70 */ - u32 tcon0_ttl_timing1; /* 0x74 */ - u32 tcon0_ttl_timing2; /* 0x78 */ - u32 tcon0_ttl_timing3; /* 0x7c */ - u32 tcon0_ttl_timing4; /* 0x80 */ - u32 tcon0_lvds_intf; /* 0x84 */ - u32 tcon0_io_polarity; /* 0x88 */ - u32 tcon0_io_tristate; /* 0x8c */ - u32 tcon1_ctrl; /* 0x90 */ - u32 tcon1_timing_source; /* 0x94 */ - u32 tcon1_timing_scale; /* 0x98 */ - u32 tcon1_timing_out; /* 0x9c */ - u32 tcon1_timing_h; /* 0xa0 */ - u32 tcon1_timing_v; /* 0xa4 */ - u32 tcon1_timing_sync; /* 0xa8 */ - u8 res3[0x44]; /* 0xac */ - u32 tcon1_io_polarity; /* 0xf0 */ - u32 tcon1_io_tristate; /* 0xf4 */ - u8 res4[0x108]; /* 0xf8 */ - u32 mux_ctrl; /* 0x200 */ - u8 res5[0x1c]; /* 0x204 */ - u32 lvds_ana0; /* 0x220 */ - u32 lvds_ana1; /* 0x224 */ -}; - struct sunxi_hdmi_reg { u32 version_id; /* 0x000 */ u32 ctrl; /* 0x004 */ @@ -346,63 +300,6 @@ struct sunxi_tve_reg { #define SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888 (0x09 << 8) #define SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE 1 -/* - * LCDC register constants. - */ -#define SUNXI_LCDC_X(x) (((x) - 1) << 16) -#define SUNXI_LCDC_Y(y) (((y) - 1) << 0) -#define SUNXI_LCDC_TCON_VSYNC_MASK (1 << 24) -#define SUNXI_LCDC_TCON_HSYNC_MASK (1 << 25) -#define SUNXI_LCDC_CTRL_IO_MAP_MASK (1 << 0) -#define SUNXI_LCDC_CTRL_IO_MAP_TCON0 (0 << 0) -#define SUNXI_LCDC_CTRL_IO_MAP_TCON1 (1 << 0) -#define SUNXI_LCDC_CTRL_TCON_ENABLE (1 << 31) -#define SUNXI_LCDC_TCON0_FRM_CTRL_RGB666 ((1 << 31) | (0 << 4)) -#define SUNXI_LCDC_TCON0_FRM_CTRL_RGB565 ((1 << 31) | (5 << 4)) -#define SUNXI_LCDC_TCON0_FRM_SEED 0x11111111 -#define SUNXI_LCDC_TCON0_FRM_TAB0 0x01010000 -#define SUNXI_LCDC_TCON0_FRM_TAB1 0x15151111 -#define SUNXI_LCDC_TCON0_FRM_TAB2 0x57575555 -#define SUNXI_LCDC_TCON0_FRM_TAB3 0x7f7f7777 -#define SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(n) (((n) & 0x1f) << 4) -#define SUNXI_LCDC_TCON0_CTRL_ENABLE (1 << 31) -#define SUNXI_LCDC_TCON0_DCLK_DIV(n) ((n) << 0) -#define SUNXI_LCDC_TCON0_DCLK_ENABLE (0xf << 28) -#define SUNXI_LCDC_TCON0_TIMING_H_BP(n) (((n) - 1) << 0) -#define SUNXI_LCDC_TCON0_TIMING_H_TOTAL(n) (((n) - 1) << 16) -#define SUNXI_LCDC_TCON0_TIMING_V_BP(n) (((n) - 1) << 0) -#define SUNXI_LCDC_TCON0_TIMING_V_TOTAL(n) (((n) * 2) << 16) -#ifdef CONFIG_SUNXI_GEN_SUN6I -#define SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0 (1 << 20) -#else -#define SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0 0 /* NA */ -#endif -#define SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(n) ((n) << 26) -#define SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE (1 << 31) -#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(x) ((x) << 28) -#define SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(n) (((n) & 0x1f) << 4) -#define SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE (1 << 20) -#define SUNXI_LCDC_TCON1_CTRL_ENABLE (1 << 31) -#define SUNXI_LCDC_TCON1_TIMING_H_BP(n) (((n) - 1) << 0) -#define SUNXI_LCDC_TCON1_TIMING_H_TOTAL(n) (((n) - 1) << 16) -#define SUNXI_LCDC_TCON1_TIMING_V_BP(n) (((n) - 1) << 0) -#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL(n) ((n) << 16) -#define SUNXI_LCDC_MUX_CTRL_SRC0_MASK (0xf << 0) -#define SUNXI_LCDC_MUX_CTRL_SRC0(x) ((x) << 0) -#define SUNXI_LCDC_MUX_CTRL_SRC1_MASK (0xf << 4) -#define SUNXI_LCDC_MUX_CTRL_SRC1(x) ((x) << 4) -#ifdef CONFIG_SUNXI_GEN_SUN6I -#define SUNXI_LCDC_LVDS_ANA0 0x40040320 -#define SUNXI_LCDC_LVDS_ANA0_EN_MB (1 << 31) -#define SUNXI_LCDC_LVDS_ANA0_DRVC (1 << 24) -#define SUNXI_LCDC_LVDS_ANA0_DRVD(x) ((x) << 20) -#else -#define SUNXI_LCDC_LVDS_ANA0 0x3f310000 -#define SUNXI_LCDC_LVDS_ANA0_UPDATE (1 << 22) -#endif -#define SUNXI_LCDC_LVDS_ANA1_INIT1 (0x1f << 26 | 0x1f << 10) -#define SUNXI_LCDC_LVDS_ANA1_INIT2 (0x1f << 16 | 0x1f << 00) - /* * HDMI register constants. */ diff --git a/arch/arm/include/asm/arch-sunxi/lcdc.h b/arch/arm/include/asm/arch-sunxi/lcdc.h new file mode 100644 index 00000000000..e4c8c160ed1 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/lcdc.h @@ -0,0 +1,128 @@ +/* + * Sunxi platform timing controller register and constant defines + * + * (C) Copyright 2014 Hans de Goede + * (C) Copyright 2017 Jernej Skrabec + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _LCDC_H +#define _LCDC_H + +struct ctfb_res_modes; + +struct sunxi_lcdc_reg { + u32 ctrl; /* 0x00 */ + u32 int0; /* 0x04 */ + u32 int1; /* 0x08 */ + u8 res0[0x04]; /* 0x0c */ + u32 tcon0_frm_ctrl; /* 0x10 */ + u32 tcon0_frm_seed[6]; /* 0x14 */ + u32 tcon0_frm_table[4]; /* 0x2c */ + u8 res1[4]; /* 0x3c */ + u32 tcon0_ctrl; /* 0x40 */ + u32 tcon0_dclk; /* 0x44 */ + u32 tcon0_timing_active; /* 0x48 */ + u32 tcon0_timing_h; /* 0x4c */ + u32 tcon0_timing_v; /* 0x50 */ + u32 tcon0_timing_sync; /* 0x54 */ + u32 tcon0_hv_intf; /* 0x58 */ + u8 res2[0x04]; /* 0x5c */ + u32 tcon0_cpu_intf; /* 0x60 */ + u32 tcon0_cpu_wr_dat; /* 0x64 */ + u32 tcon0_cpu_rd_dat0; /* 0x68 */ + u32 tcon0_cpu_rd_dat1; /* 0x6c */ + u32 tcon0_ttl_timing0; /* 0x70 */ + u32 tcon0_ttl_timing1; /* 0x74 */ + u32 tcon0_ttl_timing2; /* 0x78 */ + u32 tcon0_ttl_timing3; /* 0x7c */ + u32 tcon0_ttl_timing4; /* 0x80 */ + u32 tcon0_lvds_intf; /* 0x84 */ + u32 tcon0_io_polarity; /* 0x88 */ + u32 tcon0_io_tristate; /* 0x8c */ + u32 tcon1_ctrl; /* 0x90 */ + u32 tcon1_timing_source; /* 0x94 */ + u32 tcon1_timing_scale; /* 0x98 */ + u32 tcon1_timing_out; /* 0x9c */ + u32 tcon1_timing_h; /* 0xa0 */ + u32 tcon1_timing_v; /* 0xa4 */ + u32 tcon1_timing_sync; /* 0xa8 */ + u8 res3[0x44]; /* 0xac */ + u32 tcon1_io_polarity; /* 0xf0 */ + u32 tcon1_io_tristate; /* 0xf4 */ + u8 res4[0x108]; /* 0xf8 */ + u32 mux_ctrl; /* 0x200 */ + u8 res5[0x1c]; /* 0x204 */ + u32 lvds_ana0; /* 0x220 */ + u32 lvds_ana1; /* 0x224 */ +}; + +/* + * LCDC register constants. + */ +#define SUNXI_LCDC_X(x) (((x) - 1) << 16) +#define SUNXI_LCDC_Y(y) (((y) - 1) << 0) +#define SUNXI_LCDC_TCON_VSYNC_MASK (1 << 24) +#define SUNXI_LCDC_TCON_HSYNC_MASK (1 << 25) +#define SUNXI_LCDC_CTRL_IO_MAP_MASK (1 << 0) +#define SUNXI_LCDC_CTRL_IO_MAP_TCON0 (0 << 0) +#define SUNXI_LCDC_CTRL_IO_MAP_TCON1 (1 << 0) +#define SUNXI_LCDC_CTRL_TCON_ENABLE (1 << 31) +#define SUNXI_LCDC_TCON0_FRM_CTRL_RGB666 ((1 << 31) | (0 << 4)) +#define SUNXI_LCDC_TCON0_FRM_CTRL_RGB565 ((1 << 31) | (5 << 4)) +#define SUNXI_LCDC_TCON0_FRM_SEED 0x11111111 +#define SUNXI_LCDC_TCON0_FRM_TAB0 0x01010000 +#define SUNXI_LCDC_TCON0_FRM_TAB1 0x15151111 +#define SUNXI_LCDC_TCON0_FRM_TAB2 0x57575555 +#define SUNXI_LCDC_TCON0_FRM_TAB3 0x7f7f7777 +#define SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(n) (((n) & 0x1f) << 4) +#define SUNXI_LCDC_TCON0_CTRL_ENABLE (1 << 31) +#define SUNXI_LCDC_TCON0_DCLK_DIV(n) ((n) << 0) +#define SUNXI_LCDC_TCON0_DCLK_ENABLE (0xf << 28) +#define SUNXI_LCDC_TCON0_TIMING_H_BP(n) (((n) - 1) << 0) +#define SUNXI_LCDC_TCON0_TIMING_H_TOTAL(n) (((n) - 1) << 16) +#define SUNXI_LCDC_TCON0_TIMING_V_BP(n) (((n) - 1) << 0) +#define SUNXI_LCDC_TCON0_TIMING_V_TOTAL(n) (((n) * 2) << 16) +#ifdef CONFIG_SUNXI_GEN_SUN6I +#define SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0 (1 << 20) +#else +#define SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0 0 /* NA */ +#endif +#define SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(n) ((n) << 26) +#define SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE (1 << 31) +#define SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(x) ((x) << 28) +#define SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(n) (((n) & 0x1f) << 4) +#define SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE (1 << 20) +#define SUNXI_LCDC_TCON1_CTRL_ENABLE (1 << 31) +#define SUNXI_LCDC_TCON1_TIMING_H_BP(n) (((n) - 1) << 0) +#define SUNXI_LCDC_TCON1_TIMING_H_TOTAL(n) (((n) - 1) << 16) +#define SUNXI_LCDC_TCON1_TIMING_V_BP(n) (((n) - 1) << 0) +#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL(n) ((n) << 16) +#define SUNXI_LCDC_MUX_CTRL_SRC0_MASK (0xf << 0) +#define SUNXI_LCDC_MUX_CTRL_SRC0(x) ((x) << 0) +#define SUNXI_LCDC_MUX_CTRL_SRC1_MASK (0xf << 4) +#define SUNXI_LCDC_MUX_CTRL_SRC1(x) ((x) << 4) +#ifdef CONFIG_SUNXI_GEN_SUN6I +#define SUNXI_LCDC_LVDS_ANA0 0x40040320 +#define SUNXI_LCDC_LVDS_ANA0_EN_MB (1 << 31) +#define SUNXI_LCDC_LVDS_ANA0_DRVC (1 << 24) +#define SUNXI_LCDC_LVDS_ANA0_DRVD(x) ((x) << 20) +#else +#define SUNXI_LCDC_LVDS_ANA0 0x3f310000 +#define SUNXI_LCDC_LVDS_ANA0_UPDATE (1 << 22) +#endif +#define SUNXI_LCDC_LVDS_ANA1_INIT1 (0x1f << 26 | 0x1f << 10) +#define SUNXI_LCDC_LVDS_ANA1_INIT2 (0x1f << 16 | 0x1f << 00) + +void lcdc_init(struct sunxi_lcdc_reg * const lcdc); +void lcdc_enable(struct sunxi_lcdc_reg * const lcdc, int depth); +void lcdc_tcon0_mode_set(struct sunxi_lcdc_reg * const lcdc, + const struct ctfb_res_modes *mode, + int clk_div, bool for_ext_vga_dac, + int depth, int dclk_phase); +void lcdc_tcon1_mode_set(struct sunxi_lcdc_reg * const lcdc, + const struct ctfb_res_modes *mode, + bool ext_hvsync, bool is_composite); + +#endif /* _LCDC_H */ diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 7cd6d286584..a80af3104d1 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -51,7 +51,6 @@ obj-$(CONFIG_VIDEO_MXS) += mxsfb.o videomodes.o obj-$(CONFIG_VIDEO_OMAP3) += omap3_dss.o obj-$(CONFIG_VIDEO_SANDBOX_SDL) += sandbox_sdl.o obj-$(CONFIG_VIDEO_SM501) += sm501.o -obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o videomodes.o obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o obj-$(CONFIG_VIDEO_VESA) += vesa.o @@ -64,3 +63,4 @@ obj-${CONFIG_EXYNOS_FB} += exynos/ obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/ obj-y += bridge/ +obj-y += sunxi/ diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile new file mode 100644 index 00000000000..dfc9b47a1f6 --- /dev/null +++ b/drivers/video/sunxi/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2000-2007 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o ../videomodes.o diff --git a/drivers/video/sunxi/lcdc.c b/drivers/video/sunxi/lcdc.c new file mode 100644 index 00000000000..caf1859b0db --- /dev/null +++ b/drivers/video/sunxi/lcdc.c @@ -0,0 +1,207 @@ +/* + * Timing controller driver for Allwinner SoCs. + * + * (C) Copyright 2013-2014 Luc Verhaegen + * (C) Copyright 2014-2015 Hans de Goede + * (C) Copyright 2017 Jernej Skrabec + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#include +#include + +#include "../videomodes.h" + +static int lcdc_get_clk_delay(const struct ctfb_res_modes *mode, int tcon) +{ + int delay; + + delay = mode->lower_margin + mode->vsync_len + + mode->upper_margin; + if (mode->vmode == FB_VMODE_INTERLACED) + delay /= 2; + if (tcon == 1) + delay -= 2; + + return (delay > 30) ? 30 : delay; +} + +void lcdc_init(struct sunxi_lcdc_reg * const lcdc) +{ + /* Init lcdc */ + writel(0, &lcdc->ctrl); /* Disable tcon */ + writel(0, &lcdc->int0); /* Disable all interrupts */ + + /* Disable tcon0 dot clock */ + clrbits_le32(&lcdc->tcon0_dclk, SUNXI_LCDC_TCON0_DCLK_ENABLE); + + /* Set all io lines to tristate */ + writel(0xffffffff, &lcdc->tcon0_io_tristate); + writel(0xffffffff, &lcdc->tcon1_io_tristate); +} + +void lcdc_enable(struct sunxi_lcdc_reg * const lcdc, int depth) +{ + setbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE); +#ifdef CONFIG_VIDEO_LCD_IF_LVDS + setbits_le32(&lcdc->tcon0_lvds_intf, SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE); + setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0); +#ifdef CONFIG_SUNXI_GEN_SUN6I + udelay(2); /* delay at least 1200 ns */ + setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_EN_MB); + udelay(2); /* delay at least 1200 ns */ + setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVC); + if (depth == 18) + setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0x7)); + else + setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0xf)); +#else + setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE); + udelay(2); /* delay at least 1200 ns */ + setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT1); + udelay(1); /* delay at least 120 ns */ + setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT2); + setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE); +#endif +#endif +} + +void lcdc_tcon0_mode_set(struct sunxi_lcdc_reg * const lcdc, + const struct ctfb_res_modes *mode, + int clk_div, bool for_ext_vga_dac, + int depth, int dclk_phase) +{ + int bp, clk_delay, total, val; + + /* Use tcon0 */ + clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK, + SUNXI_LCDC_CTRL_IO_MAP_TCON0); + + clk_delay = lcdc_get_clk_delay(mode, 0); + writel(SUNXI_LCDC_TCON0_CTRL_ENABLE | + SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl); + + writel(SUNXI_LCDC_TCON0_DCLK_ENABLE | + SUNXI_LCDC_TCON0_DCLK_DIV(clk_div), &lcdc->tcon0_dclk); + + writel(SUNXI_LCDC_X(mode->xres) | + SUNXI_LCDC_Y(mode->yres), &lcdc->tcon0_timing_active); + + bp = mode->hsync_len + mode->left_margin; + total = mode->xres + mode->right_margin + bp; + writel(SUNXI_LCDC_TCON0_TIMING_H_TOTAL(total) | + SUNXI_LCDC_TCON0_TIMING_H_BP(bp), &lcdc->tcon0_timing_h); + + bp = mode->vsync_len + mode->upper_margin; + total = mode->yres + mode->lower_margin + bp; + writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) | + SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v); + +#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL + writel(SUNXI_LCDC_X(mode->hsync_len) | + SUNXI_LCDC_Y(mode->vsync_len), &lcdc->tcon0_timing_sync); + + writel(0, &lcdc->tcon0_hv_intf); + writel(0, &lcdc->tcon0_cpu_intf); +#endif +#ifdef CONFIG_VIDEO_LCD_IF_LVDS + val = (depth == 18) ? 1 : 0; + writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val) | + SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0, &lcdc->tcon0_lvds_intf); +#endif + + if (depth == 18 || depth == 16) { + writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[0]); + writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[1]); + writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[2]); + writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[3]); + writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[4]); + writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[5]); + writel(SUNXI_LCDC_TCON0_FRM_TAB0, &lcdc->tcon0_frm_table[0]); + writel(SUNXI_LCDC_TCON0_FRM_TAB1, &lcdc->tcon0_frm_table[1]); + writel(SUNXI_LCDC_TCON0_FRM_TAB2, &lcdc->tcon0_frm_table[2]); + writel(SUNXI_LCDC_TCON0_FRM_TAB3, &lcdc->tcon0_frm_table[3]); + writel(((depth == 18) ? + SUNXI_LCDC_TCON0_FRM_CTRL_RGB666 : + SUNXI_LCDC_TCON0_FRM_CTRL_RGB565), + &lcdc->tcon0_frm_ctrl); + } + + val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(dclk_phase); + if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT)) + val |= SUNXI_LCDC_TCON_HSYNC_MASK; + if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) + val |= SUNXI_LCDC_TCON_VSYNC_MASK; + +#ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH + if (for_ext_vga_dac) + val = 0; +#endif + writel(val, &lcdc->tcon0_io_polarity); + + writel(0, &lcdc->tcon0_io_tristate); +} + +void lcdc_tcon1_mode_set(struct sunxi_lcdc_reg * const lcdc, + const struct ctfb_res_modes *mode, + bool ext_hvsync, bool is_composite) +{ + int bp, clk_delay, total, val, yres; + + /* Use tcon1 */ + clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK, + SUNXI_LCDC_CTRL_IO_MAP_TCON1); + + clk_delay = lcdc_get_clk_delay(mode, 1); + writel(SUNXI_LCDC_TCON1_CTRL_ENABLE | + ((mode->vmode == FB_VMODE_INTERLACED) ? + SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE : 0) | + SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon1_ctrl); + + yres = mode->yres; + if (mode->vmode == FB_VMODE_INTERLACED) + yres /= 2; + writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), + &lcdc->tcon1_timing_source); + writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), + &lcdc->tcon1_timing_scale); + writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), + &lcdc->tcon1_timing_out); + + bp = mode->hsync_len + mode->left_margin; + total = mode->xres + mode->right_margin + bp; + writel(SUNXI_LCDC_TCON1_TIMING_H_TOTAL(total) | + SUNXI_LCDC_TCON1_TIMING_H_BP(bp), &lcdc->tcon1_timing_h); + + bp = mode->vsync_len + mode->upper_margin; + total = mode->yres + mode->lower_margin + bp; + if (mode->vmode == FB_VMODE_NONINTERLACED) + total *= 2; + writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(total) | + SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc->tcon1_timing_v); + + writel(SUNXI_LCDC_X(mode->hsync_len) | + SUNXI_LCDC_Y(mode->vsync_len), &lcdc->tcon1_timing_sync); + + if (ext_hvsync) { + val = 0; + if (mode->sync & FB_SYNC_HOR_HIGH_ACT) + val |= SUNXI_LCDC_TCON_HSYNC_MASK; + if (mode->sync & FB_SYNC_VERT_HIGH_ACT) + val |= SUNXI_LCDC_TCON_VSYNC_MASK; + writel(val, &lcdc->tcon1_io_polarity); + + clrbits_le32(&lcdc->tcon1_io_tristate, + SUNXI_LCDC_TCON_VSYNC_MASK | + SUNXI_LCDC_TCON_HSYNC_MASK); + } + +#ifdef CONFIG_MACH_SUN5I + if (is_composite) + clrsetbits_le32(&lcdc->mux_ctrl, SUNXI_LCDC_MUX_CTRL_SRC0_MASK, + SUNXI_LCDC_MUX_CTRL_SRC0(1)); +#endif +} diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c new file mode 100644 index 00000000000..48192ef87ea --- /dev/null +++ b/drivers/video/sunxi/sunxi_display.c @@ -0,0 +1,1436 @@ +/* + * Display driver for Allwinner SoCs. + * + * (C) Copyright 2013-2014 Luc Verhaegen + * (C) Copyright 2014-2015 Hans de Goede + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../videomodes.h" +#include "../anx9804.h" +#include "../hitachi_tx18d42vm_lcd.h" +#include "../ssd2828.h" + +#ifdef CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW +#define PWM_ON 0 +#define PWM_OFF 1 +#else +#define PWM_ON 1 +#define PWM_OFF 0 +#endif + +DECLARE_GLOBAL_DATA_PTR; + +enum sunxi_monitor { + sunxi_monitor_none, + sunxi_monitor_dvi, + sunxi_monitor_hdmi, + sunxi_monitor_lcd, + sunxi_monitor_vga, + sunxi_monitor_composite_pal, + sunxi_monitor_composite_ntsc, + sunxi_monitor_composite_pal_m, + sunxi_monitor_composite_pal_nc, +}; +#define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc + +struct sunxi_display { + GraphicDevice graphic_device; + enum sunxi_monitor monitor; + unsigned int depth; + unsigned int fb_addr; + unsigned int fb_size; +} sunxi_display; + +const struct ctfb_res_modes composite_video_modes[2] = { + /* x y hz pixclk ps/kHz le ri up lo hs vs s vmode */ + { 720, 576, 50, 37037, 27000, 137, 5, 20, 27, 2, 2, 0, FB_VMODE_INTERLACED }, + { 720, 480, 60, 37037, 27000, 116, 20, 16, 27, 2, 2, 0, FB_VMODE_INTERLACED }, +}; + +#ifdef CONFIG_VIDEO_HDMI + +/* + * Wait up to 200ms for value to be set in given part of reg. + */ +static int await_completion(u32 *reg, u32 mask, u32 val) +{ + unsigned long tmo = timer_get_us() + 200000; + + while ((readl(reg) & mask) != val) { + if (timer_get_us() > tmo) { + printf("DDC: timeout reading EDID\n"); + return -ETIME; + } + } + return 0; +} + +static int sunxi_hdmi_hpd_detect(int hpd_delay) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_hdmi_reg * const hdmi = + (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; + unsigned long tmo = timer_get_us() + hpd_delay * 1000; + + /* Set pll3 to 300MHz */ + clock_set_pll3(300000000); + + /* Set hdmi parent to pll3 */ + clrsetbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_PLL_MASK, + CCM_HDMI_CTRL_PLL3); + + /* Set ahb gating to pass */ +#ifdef CONFIG_SUNXI_GEN_SUN6I + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI); +#endif + setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI); + + /* Clock on */ + setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE); + + writel(SUNXI_HDMI_CTRL_ENABLE, &hdmi->ctrl); + writel(SUNXI_HDMI_PAD_CTRL0_HDP, &hdmi->pad_ctrl0); + + while (timer_get_us() < tmo) { + if (readl(&hdmi->hpd) & SUNXI_HDMI_HPD_DETECT) + return 1; + } + + return 0; +} + +static void sunxi_hdmi_shutdown(void) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_hdmi_reg * const hdmi = + (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; + + clrbits_le32(&hdmi->ctrl, SUNXI_HDMI_CTRL_ENABLE); + clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE); + clrbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI); +#ifdef CONFIG_SUNXI_GEN_SUN6I + clrbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI); +#endif + clock_set_pll3(0); +} + +static int sunxi_hdmi_ddc_do_command(u32 cmnd, int offset, int n) +{ + struct sunxi_hdmi_reg * const hdmi = + (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; + + setbits_le32(&hdmi->ddc_fifo_ctrl, SUNXI_HDMI_DDC_FIFO_CTRL_CLEAR); + writel(SUNXI_HMDI_DDC_ADDR_EDDC_SEGMENT(offset >> 8) | + SUNXI_HMDI_DDC_ADDR_EDDC_ADDR | + SUNXI_HMDI_DDC_ADDR_OFFSET(offset) | + SUNXI_HMDI_DDC_ADDR_SLAVE_ADDR, &hdmi->ddc_addr); +#ifndef CONFIG_MACH_SUN6I + writel(n, &hdmi->ddc_byte_count); + writel(cmnd, &hdmi->ddc_cmnd); +#else + writel(n << 16 | cmnd, &hdmi->ddc_cmnd); +#endif + setbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_START); + + return await_completion(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_START, 0); +} + +static int sunxi_hdmi_ddc_read(int offset, u8 *buf, int count) +{ + struct sunxi_hdmi_reg * const hdmi = + (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; + int i, n; + + while (count > 0) { + if (count > 16) + n = 16; + else + n = count; + + if (sunxi_hdmi_ddc_do_command( + SUNXI_HDMI_DDC_CMND_EXPLICIT_EDDC_READ, + offset, n)) + return -ETIME; + + for (i = 0; i < n; i++) + *buf++ = readb(&hdmi->ddc_fifo_data); + + offset += n; + count -= n; + } + + return 0; +} + +static int sunxi_hdmi_edid_get_block(int block, u8 *buf) +{ + int r, retries = 2; + + do { + r = sunxi_hdmi_ddc_read(block * 128, buf, 128); + if (r) + continue; + r = edid_check_checksum(buf); + if (r) { + printf("EDID block %d: checksum error%s\n", + block, retries ? ", retrying" : ""); + } + } while (r && retries--); + + return r; +} + +static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) +{ + struct edid1_info edid1; + struct edid_cea861_info cea681[4]; + struct edid_detailed_timing *t = + (struct edid_detailed_timing *)edid1.monitor_details.timing; + struct sunxi_hdmi_reg * const hdmi = + (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + int i, r, ext_blocks = 0; + + /* SUNXI_HDMI_CTRL_ENABLE & PAD_CTRL0 are already set by hpd_detect */ + writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE, + &hdmi->pad_ctrl1); + writel(SUNXI_HDMI_PLL_CTRL | SUNXI_HDMI_PLL_CTRL_DIV(15), + &hdmi->pll_ctrl); + writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0); + + /* Reset i2c controller */ + setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE); + writel(SUNXI_HMDI_DDC_CTRL_ENABLE | + SUNXI_HMDI_DDC_CTRL_SDA_ENABLE | + SUNXI_HMDI_DDC_CTRL_SCL_ENABLE | + SUNXI_HMDI_DDC_CTRL_RESET, &hdmi->ddc_ctrl); + if (await_completion(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_RESET, 0)) + return -EIO; + + writel(SUNXI_HDMI_DDC_CLOCK, &hdmi->ddc_clock); +#ifndef CONFIG_MACH_SUN6I + writel(SUNXI_HMDI_DDC_LINE_CTRL_SDA_ENABLE | + SUNXI_HMDI_DDC_LINE_CTRL_SCL_ENABLE, &hdmi->ddc_line_ctrl); +#endif + + r = sunxi_hdmi_edid_get_block(0, (u8 *)&edid1); + if (r == 0) { + r = edid_check_info(&edid1); + if (r) { + printf("EDID: invalid EDID data\n"); + r = -EINVAL; + } + } + if (r == 0) { + ext_blocks = edid1.extension_flag; + if (ext_blocks > 4) + ext_blocks = 4; + for (i = 0; i < ext_blocks; i++) { + if (sunxi_hdmi_edid_get_block(1 + i, + (u8 *)&cea681[i]) != 0) { + ext_blocks = i; + break; + } + } + } + + /* Disable DDC engine, no longer needed */ + clrbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_ENABLE); + clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE); + + if (r) + return r; + + /* We want version 1.3 or 1.2 with detailed timing info */ + if (edid1.version != 1 || (edid1.revision < 3 && + !EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(edid1))) { + printf("EDID: unsupported version %d.%d\n", + edid1.version, edid1.revision); + return -EINVAL; + } + + /* Take the first usable detailed timing */ + for (i = 0; i < 4; i++, t++) { + r = video_edid_dtd_to_ctfb_res_modes(t, mode); + if (r == 0) + break; + } + if (i == 4) { + printf("EDID: no usable detailed timing found\n"); + return -ENOENT; + } + + /* Check for basic audio support, if found enable hdmi output */ + sunxi_display.monitor = sunxi_monitor_dvi; + for (i = 0; i < ext_blocks; i++) { + if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG || + cea681[i].revision < 2) + continue; + + if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i])) + sunxi_display.monitor = sunxi_monitor_hdmi; + } + + return 0; +} + +#endif /* CONFIG_VIDEO_HDMI */ + +#ifdef CONFIG_MACH_SUN4I +/* + * Testing has shown that on sun4i the display backend engine does not have + * deep enough fifo-s causing flickering / tearing in full-hd mode due to + * fifo underruns. So on sun4i we use the display frontend engine to do the + * dma from memory, as the frontend does have deep enough fifo-s. + */ + +static const u32 sun4i_vert_coef[32] = { + 0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, + 0x00063efc, 0xff083dfc, 0x000a3bfb, 0xff0d39fb, + 0xff0f37fb, 0xff1136fa, 0xfe1433fb, 0xfe1631fb, + 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc, + 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd, + 0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff, + 0xfb370fff, 0xfb390dff, 0xfb3b0a00, 0xfc3d08ff, + 0xfc3e0600, 0xfd3f0400, 0xfe3f0300, 0xff400100, +}; + +static const u32 sun4i_horz_coef[64] = { + 0x40000000, 0x00000000, 0x40fe0000, 0x0000ff03, + 0x3ffd0000, 0x0000ff05, 0x3ffc0000, 0x0000ff06, + 0x3efb0000, 0x0000ff08, 0x3dfb0000, 0x0000ff09, + 0x3bfa0000, 0x0000fe0d, 0x39fa0000, 0x0000fe0f, + 0x38fa0000, 0x0000fe10, 0x36fa0000, 0x0000fe12, + 0x33fa0000, 0x0000fd16, 0x31fa0000, 0x0000fd18, + 0x2ffa0000, 0x0000fd1a, 0x2cfa0000, 0x0000fc1e, + 0x29fa0000, 0x0000fc21, 0x27fb0000, 0x0000fb23, + 0x24fb0000, 0x0000fb26, 0x21fb0000, 0x0000fb29, + 0x1ffc0000, 0x0000fa2b, 0x1cfc0000, 0x0000fa2e, + 0x19fd0000, 0x0000fa30, 0x16fd0000, 0x0000fa33, + 0x14fd0000, 0x0000fa35, 0x11fe0000, 0x0000fa37, + 0x0ffe0000, 0x0000fa39, 0x0dfe0000, 0x0000fa3b, + 0x0afe0000, 0x0000fa3e, 0x08ff0000, 0x0000fb3e, + 0x06ff0000, 0x0000fb40, 0x05ff0000, 0x0000fc40, + 0x03ff0000, 0x0000fd41, 0x01ff0000, 0x0000fe42, +}; + +static void sunxi_frontend_init(void) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_de_fe_reg * const de_fe = + (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE; + int i; + + /* Clocks on */ + setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_FE0); + setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_FE0); + clock_set_de_mod_clock(&ccm->fe0_clk_cfg, 300000000); + + setbits_le32(&de_fe->enable, SUNXI_DE_FE_ENABLE_EN); + + for (i = 0; i < 32; i++) { + writel(sun4i_horz_coef[2 * i], &de_fe->ch0_horzcoef0[i]); + writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch0_horzcoef1[i]); + writel(sun4i_vert_coef[i], &de_fe->ch0_vertcoef[i]); + writel(sun4i_horz_coef[2 * i], &de_fe->ch1_horzcoef0[i]); + writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch1_horzcoef1[i]); + writel(sun4i_vert_coef[i], &de_fe->ch1_vertcoef[i]); + } + + setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_COEF_RDY); +} + +static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode, + unsigned int address) +{ + struct sunxi_de_fe_reg * const de_fe = + (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE; + + setbits_le32(&de_fe->bypass, SUNXI_DE_FE_BYPASS_CSC_BYPASS); + writel(CONFIG_SYS_SDRAM_BASE + address, &de_fe->ch0_addr); + writel(mode->xres * 4, &de_fe->ch0_stride); + writel(SUNXI_DE_FE_INPUT_FMT_ARGB8888, &de_fe->input_fmt); + writel(SUNXI_DE_FE_OUTPUT_FMT_ARGB8888, &de_fe->output_fmt); + + writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres), + &de_fe->ch0_insize); + writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres), + &de_fe->ch0_outsize); + writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_horzfact); + writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_vertfact); + + writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres), + &de_fe->ch1_insize); + writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres), + &de_fe->ch1_outsize); + writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_horzfact); + writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_vertfact); + + setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_REG_RDY); +} + +static void sunxi_frontend_enable(void) +{ + struct sunxi_de_fe_reg * const de_fe = + (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE; + + setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_FRM_START); +} +#else +static void sunxi_frontend_init(void) {} +static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode, + unsigned int address) {} +static void sunxi_frontend_enable(void) {} +#endif + +static bool sunxi_is_composite(void) +{ + switch (sunxi_display.monitor) { + case sunxi_monitor_none: + case sunxi_monitor_dvi: + case sunxi_monitor_hdmi: + case sunxi_monitor_lcd: + case sunxi_monitor_vga: + return false; + case sunxi_monitor_composite_pal: + case sunxi_monitor_composite_ntsc: + case sunxi_monitor_composite_pal_m: + case sunxi_monitor_composite_pal_nc: + return true; + } + + return false; /* Never reached */ +} + +/* + * This is the entity that mixes and matches the different layers and inputs. + * Allwinner calls it the back-end, but i like composer better. + */ +static void sunxi_composer_init(void) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_de_be_reg * const de_be = + (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE; + int i; + + sunxi_frontend_init(); + +#ifdef CONFIG_SUNXI_GEN_SUN6I + /* Reset off */ + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE_BE0); +#endif + + /* Clocks on */ + setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_BE0); +#ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */ + setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_BE0); +#endif + clock_set_de_mod_clock(&ccm->be0_clk_cfg, 300000000); + + /* Engine bug, clear registers after reset */ + for (i = 0x0800; i < 0x1000; i += 4) + writel(0, SUNXI_DE_BE0_BASE + i); + + setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_ENABLE); +} + +static u32 sunxi_rgb2yuv_coef[12] = { + 0x00000107, 0x00000204, 0x00000064, 0x00000108, + 0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808, + 0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808 +}; + +static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode, + unsigned int address) +{ + struct sunxi_de_be_reg * const de_be = + (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE; + int i; + + sunxi_frontend_mode_set(mode, address); + + writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres), + &de_be->disp_size); + writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres), + &de_be->layer0_size); +#ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */ + writel(SUNXI_DE_BE_LAYER_STRIDE(mode->xres), &de_be->layer0_stride); + writel(address << 3, &de_be->layer0_addr_low32b); + writel(address >> 29, &de_be->layer0_addr_high4b); +#else + writel(SUNXI_DE_BE_LAYER_ATTR0_SRC_FE0, &de_be->layer0_attr0_ctrl); +#endif + writel(SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888, &de_be->layer0_attr1_ctrl); + + setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_LAYER0_ENABLE); + if (mode->vmode == FB_VMODE_INTERLACED) + setbits_le32(&de_be->mode, +#ifndef CONFIG_MACH_SUN5I + SUNXI_DE_BE_MODE_DEFLICKER_ENABLE | +#endif + SUNXI_DE_BE_MODE_INTERLACE_ENABLE); + + if (sunxi_is_composite()) { + writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE, + &de_be->output_color_ctrl); + for (i = 0; i < 12; i++) + writel(sunxi_rgb2yuv_coef[i], + &de_be->output_color_coef[i]); + } +} + +static void sunxi_composer_enable(void) +{ + struct sunxi_de_be_reg * const de_be = + (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE; + + sunxi_frontend_enable(); + + setbits_le32(&de_be->reg_ctrl, SUNXI_DE_BE_REG_CTRL_LOAD_REGS); + setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_START); +} + +/* + * LCDC, what allwinner calls a CRTC, so timing controller and serializer. + */ +static void sunxi_lcdc_pll_set(int tcon, int dotclock, + int *clk_div, int *clk_double) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + int value, n, m, min_m, max_m, diff; + int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF; + int best_double = 0; + bool use_mipi_pll = false; + + if (tcon == 0) { +#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL + min_m = 6; + max_m = 127; +#endif +#ifdef CONFIG_VIDEO_LCD_IF_LVDS + min_m = max_m = 7; +#endif + } else { + min_m = 1; + max_m = 15; + } + + /* + * Find the lowest divider resulting in a matching clock, if there + * is no match, pick the closest lower clock, as monitors tend to + * not sync to higher frequencies. + */ + for (m = min_m; m <= max_m; m++) { + n = (m * dotclock) / 3000; + + if ((n >= 9) && (n <= 127)) { + value = (3000 * n) / m; + diff = dotclock - value; + if (diff < best_diff) { + best_diff = diff; + best_m = m; + best_n = n; + best_double = 0; + } + } + + /* These are just duplicates */ + if (!(m & 1)) + continue; + + n = (m * dotclock) / 6000; + if ((n >= 9) && (n <= 127)) { + value = (6000 * n) / m; + diff = dotclock - value; + if (diff < best_diff) { + best_diff = diff; + best_m = m; + best_n = n; + best_double = 1; + } + } + } + +#ifdef CONFIG_MACH_SUN6I + /* + * Use the MIPI pll if we've been unable to find any matching setting + * for PLL3, this happens with high dotclocks because of min_m = 6. + */ + if (tcon == 0 && best_n == 0) { + use_mipi_pll = true; + best_m = 6; /* Minimum m for tcon0 */ + } + + if (use_mipi_pll) { + clock_set_pll3(297000000); /* Fix the video pll at 297 MHz */ + clock_set_mipi_pll(best_m * dotclock * 1000); + debug("dotclock: %dkHz = %dkHz via mipi pll\n", + dotclock, clock_get_mipi_pll() / best_m / 1000); + } else +#endif + { + clock_set_pll3(best_n * 3000000); + debug("dotclock: %dkHz = %dkHz: (%d * 3MHz * %d) / %d\n", + dotclock, + (best_double + 1) * clock_get_pll3() / best_m / 1000, + best_double + 1, best_n, best_m); + } + + if (tcon == 0) { + u32 pll; + + if (use_mipi_pll) + pll = CCM_LCD_CH0_CTRL_MIPI_PLL; + else if (best_double) + pll = CCM_LCD_CH0_CTRL_PLL3_2X; + else + pll = CCM_LCD_CH0_CTRL_PLL3; + + writel(CCM_LCD_CH0_CTRL_GATE | CCM_LCD_CH0_CTRL_RST | pll, + &ccm->lcd0_ch0_clk_cfg); + } else { + writel(CCM_LCD_CH1_CTRL_GATE | + (best_double ? CCM_LCD_CH1_CTRL_PLL3_2X : + CCM_LCD_CH1_CTRL_PLL3) | + CCM_LCD_CH1_CTRL_M(best_m), &ccm->lcd0_ch1_clk_cfg); + if (sunxi_is_composite()) + setbits_le32(&ccm->lcd0_ch1_clk_cfg, + CCM_LCD_CH1_CTRL_HALF_SCLK1); + } + + *clk_div = best_m; + *clk_double = best_double; +} + +static void sunxi_lcdc_init(void) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_lcdc_reg * const lcdc = + (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; + + /* Reset off */ +#ifdef CONFIG_SUNXI_GEN_SUN6I + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0); +#else + setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_RST); +#endif + + /* Clock on */ + setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0); +#ifdef CONFIG_VIDEO_LCD_IF_LVDS +#ifdef CONFIG_SUNXI_GEN_SUN6I + setbits_le32(&ccm->ahb_reset2_cfg, 1 << AHB_RESET_OFFSET_LVDS); +#else + setbits_le32(&ccm->lvds_clk_cfg, CCM_LVDS_CTRL_RST); +#endif +#endif + + lcdc_init(lcdc); +} + +static void sunxi_lcdc_panel_enable(void) +{ + int pin, reset_pin; + + /* + * Start with backlight disabled to avoid the screen flashing to + * white while the lcd inits. + */ + pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN); + if (pin >= 0) { + gpio_request(pin, "lcd_backlight_enable"); + gpio_direction_output(pin, 0); + } + + pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM); + if (pin >= 0) { + gpio_request(pin, "lcd_backlight_pwm"); + gpio_direction_output(pin, PWM_OFF); + } + + reset_pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_RESET); + if (reset_pin >= 0) { + gpio_request(reset_pin, "lcd_reset"); + gpio_direction_output(reset_pin, 0); /* Assert reset */ + } + + /* Give the backlight some time to turn off and power up the panel. */ + mdelay(40); + pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_POWER); + if (pin >= 0) { + gpio_request(pin, "lcd_power"); + gpio_direction_output(pin, 1); + } + + if (reset_pin >= 0) + gpio_direction_output(reset_pin, 1); /* De-assert reset */ +} + +static void sunxi_lcdc_backlight_enable(void) +{ + int pin; + + /* + * We want to have scanned out at least one frame before enabling the + * backlight to avoid the screen flashing to white when we enable it. + */ + mdelay(40); + + pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN); + if (pin >= 0) + gpio_direction_output(pin, 1); + + pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM); +#ifdef SUNXI_PWM_PIN0 + if (pin == SUNXI_PWM_PIN0) { + writel(SUNXI_PWM_CTRL_POLARITY0(PWM_ON) | + SUNXI_PWM_CTRL_ENABLE0 | + SUNXI_PWM_CTRL_PRESCALE0(0xf), SUNXI_PWM_CTRL_REG); + writel(SUNXI_PWM_PERIOD_80PCT, SUNXI_PWM_CH0_PERIOD); + sunxi_gpio_set_cfgpin(pin, SUNXI_PWM_MUX); + return; + } +#endif + if (pin >= 0) + gpio_direction_output(pin, PWM_ON); +} + +static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode, + bool for_ext_vga_dac) +{ + struct sunxi_lcdc_reg * const lcdc = + (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; + int clk_div, clk_double, pin; + +#if defined CONFIG_MACH_SUN8I && defined CONFIG_VIDEO_LCD_IF_LVDS + for (pin = SUNXI_GPD(18); pin <= SUNXI_GPD(27); pin++) { +#else + for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++) { +#endif +#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL + sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0); +#endif +#ifdef CONFIG_VIDEO_LCD_IF_LVDS + sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0); +#endif +#ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804 + sunxi_gpio_set_drv(pin, 3); +#endif + } + + sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double); + + lcdc_tcon0_mode_set(lcdc, mode, clk_div, for_ext_vga_dac, + sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE); +} + +#if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE +static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode, + int *clk_div, int *clk_double, + bool use_portd_hvsync) +{ + struct sunxi_lcdc_reg * const lcdc = + (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; + + lcdc_tcon1_mode_set(lcdc, mode, use_portd_hvsync, + sunxi_is_composite()); + + if (use_portd_hvsync) { + sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0); + sunxi_gpio_set_cfgpin(SUNXI_GPD(27), SUNXI_GPD_LCD0); + } + + sunxi_lcdc_pll_set(1, mode->pixclock_khz, clk_div, clk_double); +} +#endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */ + +#ifdef CONFIG_VIDEO_HDMI + +static void sunxi_hdmi_setup_info_frames(const struct ctfb_res_modes *mode) +{ + struct sunxi_hdmi_reg * const hdmi = + (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; + u8 checksum = 0; + u8 avi_info_frame[17] = { + 0x82, 0x02, 0x0d, 0x00, 0x12, 0x00, 0x88, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + u8 vendor_info_frame[19] = { + 0x81, 0x01, 0x06, 0x29, 0x03, 0x0c, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 + }; + int i; + + if (mode->pixclock_khz <= 27000) + avi_info_frame[5] = 0x40; /* SD-modes, ITU601 colorspace */ + else + avi_info_frame[5] = 0x80; /* HD-modes, ITU709 colorspace */ + + if (mode->xres * 100 / mode->yres < 156) + avi_info_frame[5] |= 0x18; /* 4 : 3 */ + else + avi_info_frame[5] |= 0x28; /* 16 : 9 */ + + for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++) + checksum += avi_info_frame[i]; + + avi_info_frame[3] = 0x100 - checksum; + + for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++) + writeb(avi_info_frame[i], &hdmi->avi_info_frame[i]); + + writel(SUNXI_HDMI_QCP_PACKET0, &hdmi->qcp_packet0); + writel(SUNXI_HDMI_QCP_PACKET1, &hdmi->qcp_packet1); + + for (i = 0; i < ARRAY_SIZE(vendor_info_frame); i++) + writeb(vendor_info_frame[i], &hdmi->vendor_info_frame[i]); + + writel(SUNXI_HDMI_PKT_CTRL0, &hdmi->pkt_ctrl0); + writel(SUNXI_HDMI_PKT_CTRL1, &hdmi->pkt_ctrl1); + + setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_HDMI); +} + +static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode, + int clk_div, int clk_double) +{ + struct sunxi_hdmi_reg * const hdmi = + (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; + int x, y; + + /* Write clear interrupt status bits */ + writel(SUNXI_HDMI_IRQ_STATUS_BITS, &hdmi->irq); + + if (sunxi_display.monitor == sunxi_monitor_hdmi) + sunxi_hdmi_setup_info_frames(mode); + + /* Set input sync enable */ + writel(SUNXI_HDMI_UNKNOWN_INPUT_SYNC, &hdmi->unknown); + + /* Init various registers, select pll3 as clock source */ + writel(SUNXI_HDMI_VIDEO_POL_TX_CLK, &hdmi->video_polarity); + writel(SUNXI_HDMI_PAD_CTRL0_RUN, &hdmi->pad_ctrl0); + writel(SUNXI_HDMI_PAD_CTRL1, &hdmi->pad_ctrl1); + writel(SUNXI_HDMI_PLL_CTRL, &hdmi->pll_ctrl); + writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0); + + /* Setup clk div and doubler */ + clrsetbits_le32(&hdmi->pll_ctrl, SUNXI_HDMI_PLL_CTRL_DIV_MASK, + SUNXI_HDMI_PLL_CTRL_DIV(clk_div)); + if (!clk_double) + setbits_le32(&hdmi->pad_ctrl1, SUNXI_HDMI_PAD_CTRL1_HALVE); + + /* Setup timing registers */ + writel(SUNXI_HDMI_Y(mode->yres) | SUNXI_HDMI_X(mode->xres), + &hdmi->video_size); + + x = mode->hsync_len + mode->left_margin; + y = mode->vsync_len + mode->upper_margin; + writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_bp); + + x = mode->right_margin; + y = mode->lower_margin; + writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_fp); + + x = mode->hsync_len; + y = mode->vsync_len; + writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_spw); + + if (mode->sync & FB_SYNC_HOR_HIGH_ACT) + setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_HOR); + + if (mode->sync & FB_SYNC_VERT_HIGH_ACT) + setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_VER); +} + +static void sunxi_hdmi_enable(void) +{ + struct sunxi_hdmi_reg * const hdmi = + (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; + + udelay(100); + setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE); +} + +#endif /* CONFIG_VIDEO_HDMI */ + +#if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE + +static void sunxi_tvencoder_mode_set(void) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_tve_reg * const tve = + (struct sunxi_tve_reg *)SUNXI_TVE0_BASE; + + /* Reset off */ + setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_TVE_RST); + /* Clock on */ + setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0); + + switch (sunxi_display.monitor) { + case sunxi_monitor_vga: + writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | + SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | + SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl); + writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0); + writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0); + writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1); + break; + case sunxi_monitor_composite_pal_nc: + writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq); + /* Fall through */ + case sunxi_monitor_composite_pal: + writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | + SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | + SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) | + SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl); + writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0); + writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0); + writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter); + writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num); + writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num); + writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, &tve->blank_black_level); + writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1); + writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level); + writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width); + writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2); + writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num); + writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain); + writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width); + writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num); + writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para); + break; + case sunxi_monitor_composite_pal_m: + writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq); + writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst); + /* Fall through */ + case sunxi_monitor_composite_ntsc: + writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | + SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | + SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) | + SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl); + writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0); + writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0); + writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter); + writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num); + writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num); + writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, &tve->blank_black_level); + writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1); + writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level); + writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase); + writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width); + writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2); + writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level); + writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num); + writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain); + writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width); + writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num); + writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para); + break; + case sunxi_monitor_none: + case sunxi_monitor_dvi: + case sunxi_monitor_hdmi: + case sunxi_monitor_lcd: + break; + } +} + +static void sunxi_tvencoder_enable(void) +{ + struct sunxi_tve_reg * const tve = + (struct sunxi_tve_reg *)SUNXI_TVE0_BASE; + + setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE); +} + +#endif /* CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE */ + +static void sunxi_drc_init(void) +{ +#ifdef CONFIG_SUNXI_GEN_SUN6I + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* On sun6i the drc must be clocked even when in pass-through mode */ +#ifdef CONFIG_MACH_SUN8I_A33 + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_SAT); +#endif + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DRC0); + clock_set_de_mod_clock(&ccm->iep_drc0_clk_cfg, 300000000); +#endif +} + +#ifdef CONFIG_VIDEO_VGA_VIA_LCD +static void sunxi_vga_external_dac_enable(void) +{ + int pin; + + pin = sunxi_name_to_gpio(CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN); + if (pin >= 0) { + gpio_request(pin, "vga_enable"); + gpio_direction_output(pin, 1); + } +} +#endif /* CONFIG_VIDEO_VGA_VIA_LCD */ + +#ifdef CONFIG_VIDEO_LCD_SSD2828 +static int sunxi_ssd2828_init(const struct ctfb_res_modes *mode) +{ + struct ssd2828_config cfg = { + .csx_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_CS), + .sck_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_SCLK), + .sdi_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MOSI), + .sdo_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MISO), + .reset_pin = name_to_gpio(CONFIG_VIDEO_LCD_SSD2828_RESET), + .ssd2828_tx_clk_khz = CONFIG_VIDEO_LCD_SSD2828_TX_CLK * 1000, + .ssd2828_color_depth = 24, +#ifdef CONFIG_VIDEO_LCD_PANEL_MIPI_4_LANE_513_MBPS_VIA_SSD2828 + .mipi_dsi_number_of_data_lanes = 4, + .mipi_dsi_bitrate_per_data_lane_mbps = 513, + .mipi_dsi_delay_after_exit_sleep_mode_ms = 100, + .mipi_dsi_delay_after_set_display_on_ms = 200 +#else +#error MIPI LCD panel needs configuration parameters +#endif + }; + + if (cfg.csx_pin == -1 || cfg.sck_pin == -1 || cfg.sdi_pin == -1) { + printf("SSD2828: SPI pins are not properly configured\n"); + return 1; + } + if (cfg.reset_pin == -1) { + printf("SSD2828: Reset pin is not properly configured\n"); + return 1; + } + + return ssd2828_init(&cfg, mode); +} +#endif /* CONFIG_VIDEO_LCD_SSD2828 */ + +static void sunxi_engines_init(void) +{ + sunxi_composer_init(); + sunxi_lcdc_init(); + sunxi_drc_init(); +} + +static void sunxi_mode_set(const struct ctfb_res_modes *mode, + unsigned int address) +{ + int __maybe_unused clk_div, clk_double; + struct sunxi_lcdc_reg * const lcdc = + (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; + + switch (sunxi_display.monitor) { + case sunxi_monitor_none: + break; + case sunxi_monitor_dvi: + case sunxi_monitor_hdmi: +#ifdef CONFIG_VIDEO_HDMI + sunxi_composer_mode_set(mode, address); + sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0); + sunxi_hdmi_mode_set(mode, clk_div, clk_double); + sunxi_composer_enable(); + lcdc_enable(lcdc, sunxi_display.depth); + sunxi_hdmi_enable(); +#endif + break; + case sunxi_monitor_lcd: + sunxi_lcdc_panel_enable(); + if (IS_ENABLED(CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804)) { + /* + * The anx9804 needs 1.8V from eldo3, we do this here + * and not via CONFIG_AXP_ELDO3_VOLT from board_init() + * to avoid turning this on when using hdmi output. + */ + axp_set_eldo(3, 1800); + anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4, + ANX9804_DATA_RATE_1620M, + sunxi_display.depth); + } + if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) { + mdelay(50); /* Wait for lcd controller power on */ + hitachi_tx18d42vm_init(); + } + if (IS_ENABLED(CONFIG_VIDEO_LCD_TL059WV5C0)) { + unsigned int orig_i2c_bus = i2c_get_bus_num(); + i2c_set_bus_num(CONFIG_VIDEO_LCD_I2C_BUS); + i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */ + i2c_set_bus_num(orig_i2c_bus); + } + sunxi_composer_mode_set(mode, address); + sunxi_lcdc_tcon0_mode_set(mode, false); + sunxi_composer_enable(); + lcdc_enable(lcdc, sunxi_display.depth); +#ifdef CONFIG_VIDEO_LCD_SSD2828 + sunxi_ssd2828_init(mode); +#endif + sunxi_lcdc_backlight_enable(); + break; + case sunxi_monitor_vga: +#ifdef CONFIG_VIDEO_VGA + sunxi_composer_mode_set(mode, address); + sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1); + sunxi_tvencoder_mode_set(); + sunxi_composer_enable(); + lcdc_enable(lcdc, sunxi_display.depth); + sunxi_tvencoder_enable(); +#elif defined CONFIG_VIDEO_VGA_VIA_LCD + sunxi_composer_mode_set(mode, address); + sunxi_lcdc_tcon0_mode_set(mode, true); + sunxi_composer_enable(); + lcdc_enable(lcdc, sunxi_display.depth); + sunxi_vga_external_dac_enable(); +#endif + break; + case sunxi_monitor_composite_pal: + case sunxi_monitor_composite_ntsc: + case sunxi_monitor_composite_pal_m: + case sunxi_monitor_composite_pal_nc: +#ifdef CONFIG_VIDEO_COMPOSITE + sunxi_composer_mode_set(mode, address); + sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0); + sunxi_tvencoder_mode_set(); + sunxi_composer_enable(); + lcdc_enable(lcdc, sunxi_display.depth); + sunxi_tvencoder_enable(); +#endif + break; + } +} + +static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor) +{ + switch (monitor) { + case sunxi_monitor_none: return "none"; + case sunxi_monitor_dvi: return "dvi"; + case sunxi_monitor_hdmi: return "hdmi"; + case sunxi_monitor_lcd: return "lcd"; + case sunxi_monitor_vga: return "vga"; + case sunxi_monitor_composite_pal: return "composite-pal"; + case sunxi_monitor_composite_ntsc: return "composite-ntsc"; + case sunxi_monitor_composite_pal_m: return "composite-pal-m"; + case sunxi_monitor_composite_pal_nc: return "composite-pal-nc"; + } + return NULL; /* never reached */ +} + +ulong board_get_usable_ram_top(ulong total_size) +{ + return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE; +} + +static bool sunxi_has_hdmi(void) +{ +#ifdef CONFIG_VIDEO_HDMI + return true; +#else + return false; +#endif +} + +static bool sunxi_has_lcd(void) +{ + char *lcd_mode = CONFIG_VIDEO_LCD_MODE; + + return lcd_mode[0] != 0; +} + +static bool sunxi_has_vga(void) +{ +#if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_VGA_VIA_LCD + return true; +#else + return false; +#endif +} + +static bool sunxi_has_composite(void) +{ +#ifdef CONFIG_VIDEO_COMPOSITE + return true; +#else + return false; +#endif +} + +static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi) +{ + if (allow_hdmi && sunxi_has_hdmi()) + return sunxi_monitor_dvi; + else if (sunxi_has_lcd()) + return sunxi_monitor_lcd; + else if (sunxi_has_vga()) + return sunxi_monitor_vga; + else if (sunxi_has_composite()) + return sunxi_monitor_composite_pal; + else + return sunxi_monitor_none; +} + +void *video_hw_init(void) +{ + static GraphicDevice *graphic_device = &sunxi_display.graphic_device; + const struct ctfb_res_modes *mode; + struct ctfb_res_modes custom; + const char *options; +#ifdef CONFIG_VIDEO_HDMI + int ret, hpd, hpd_delay, edid; +#endif + int i, overscan_offset, overscan_x, overscan_y; + unsigned int fb_dma_addr; + char mon[16]; + char *lcd_mode = CONFIG_VIDEO_LCD_MODE; + + memset(&sunxi_display, 0, sizeof(struct sunxi_display)); + + video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, + &sunxi_display.depth, &options); +#ifdef CONFIG_VIDEO_HDMI + hpd = video_get_option_int(options, "hpd", 1); + hpd_delay = video_get_option_int(options, "hpd_delay", 500); + edid = video_get_option_int(options, "edid", 1); +#endif + overscan_x = video_get_option_int(options, "overscan_x", -1); + overscan_y = video_get_option_int(options, "overscan_y", -1); + sunxi_display.monitor = sunxi_get_default_mon(true); + video_get_option_string(options, "monitor", mon, sizeof(mon), + sunxi_get_mon_desc(sunxi_display.monitor)); + for (i = 0; i <= SUNXI_MONITOR_LAST; i++) { + if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) { + sunxi_display.monitor = i; + break; + } + } + if (i > SUNXI_MONITOR_LAST) + printf("Unknown monitor: '%s', falling back to '%s'\n", + mon, sunxi_get_mon_desc(sunxi_display.monitor)); + +#ifdef CONFIG_VIDEO_HDMI + /* If HDMI/DVI is selected do HPD & EDID, and handle fallback */ + if (sunxi_display.monitor == sunxi_monitor_dvi || + sunxi_display.monitor == sunxi_monitor_hdmi) { + /* Always call hdp_detect, as it also enables clocks, etc. */ + ret = sunxi_hdmi_hpd_detect(hpd_delay); + if (ret) { + printf("HDMI connected: "); + if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0) + mode = &custom; + } else if (hpd) { + sunxi_hdmi_shutdown(); + sunxi_display.monitor = sunxi_get_default_mon(false); + } /* else continue with hdmi/dvi without a cable connected */ + } +#endif + + switch (sunxi_display.monitor) { + case sunxi_monitor_none: + return NULL; + case sunxi_monitor_dvi: + case sunxi_monitor_hdmi: + if (!sunxi_has_hdmi()) { + printf("HDMI/DVI not supported on this board\n"); + sunxi_display.monitor = sunxi_monitor_none; + return NULL; + } + break; + case sunxi_monitor_lcd: + if (!sunxi_has_lcd()) { + printf("LCD not supported on this board\n"); + sunxi_display.monitor = sunxi_monitor_none; + return NULL; + } + sunxi_display.depth = video_get_params(&custom, lcd_mode); + mode = &custom; + break; + case sunxi_monitor_vga: + if (!sunxi_has_vga()) { + printf("VGA not supported on this board\n"); + sunxi_display.monitor = sunxi_monitor_none; + return NULL; + } + sunxi_display.depth = 18; + break; + case sunxi_monitor_composite_pal: + case sunxi_monitor_composite_ntsc: + case sunxi_monitor_composite_pal_m: + case sunxi_monitor_composite_pal_nc: + if (!sunxi_has_composite()) { + printf("Composite video not supported on this board\n"); + sunxi_display.monitor = sunxi_monitor_none; + return NULL; + } + if (sunxi_display.monitor == sunxi_monitor_composite_pal || + sunxi_display.monitor == sunxi_monitor_composite_pal_nc) + mode = &composite_video_modes[0]; + else + mode = &composite_video_modes[1]; + sunxi_display.depth = 24; + break; + } + + /* Yes these defaults are quite high, overscan on composite sucks... */ + if (overscan_x == -1) + overscan_x = sunxi_is_composite() ? 32 : 0; + if (overscan_y == -1) + overscan_y = sunxi_is_composite() ? 20 : 0; + + sunxi_display.fb_size = + (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff; + overscan_offset = (overscan_y * mode->xres + overscan_x) * 4; + /* We want to keep the fb_base for simplefb page aligned, where as + * the sunxi dma engines will happily accept an unaligned address. */ + if (overscan_offset) + sunxi_display.fb_size += 0x1000; + + if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) { + printf("Error need %dkB for fb, but only %dkB is reserved\n", + sunxi_display.fb_size >> 10, + CONFIG_SUNXI_MAX_FB_SIZE >> 10); + return NULL; + } + + printf("Setting up a %dx%d%s %s console (overscan %dx%d)\n", + mode->xres, mode->yres, + (mode->vmode == FB_VMODE_INTERLACED) ? "i" : "", + sunxi_get_mon_desc(sunxi_display.monitor), + overscan_x, overscan_y); + + gd->fb_base = gd->bd->bi_dram[0].start + + gd->bd->bi_dram[0].size - sunxi_display.fb_size; + sunxi_engines_init(); + + fb_dma_addr = gd->fb_base - CONFIG_SYS_SDRAM_BASE; + sunxi_display.fb_addr = gd->fb_base; + if (overscan_offset) { + fb_dma_addr += 0x1000 - (overscan_offset & 0xfff); + sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff; + memset((void *)gd->fb_base, 0, sunxi_display.fb_size); + flush_cache(gd->fb_base, sunxi_display.fb_size); + } + sunxi_mode_set(mode, fb_dma_addr); + + /* + * These are the only members of this structure that are used. All the + * others are driver specific. The pitch is stored in plnSizeX. + */ + graphic_device->frameAdrs = sunxi_display.fb_addr; + graphic_device->gdfIndex = GDF_32BIT_X888RGB; + graphic_device->gdfBytesPP = 4; + graphic_device->winSizeX = mode->xres - 2 * overscan_x; + graphic_device->winSizeY = mode->yres - 2 * overscan_y; + graphic_device->plnSizeX = mode->xres * graphic_device->gdfBytesPP; + + return graphic_device; +} + +/* + * Simplefb support. + */ +#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_VIDEO_DT_SIMPLEFB) +int sunxi_simplefb_setup(void *blob) +{ + static GraphicDevice *graphic_device = &sunxi_display.graphic_device; + int offset, ret; + u64 start, size; + const char *pipeline = NULL; + +#ifdef CONFIG_MACH_SUN4I +#define PIPELINE_PREFIX "de_fe0-" +#else +#define PIPELINE_PREFIX +#endif + + switch (sunxi_display.monitor) { + case sunxi_monitor_none: + return 0; + case sunxi_monitor_dvi: + case sunxi_monitor_hdmi: + pipeline = PIPELINE_PREFIX "de_be0-lcd0-hdmi"; + break; + case sunxi_monitor_lcd: + pipeline = PIPELINE_PREFIX "de_be0-lcd0"; + break; + case sunxi_monitor_vga: +#ifdef CONFIG_VIDEO_VGA + pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0"; +#elif defined CONFIG_VIDEO_VGA_VIA_LCD + pipeline = PIPELINE_PREFIX "de_be0-lcd0"; +#endif + break; + case sunxi_monitor_composite_pal: + case sunxi_monitor_composite_ntsc: + case sunxi_monitor_composite_pal_m: + case sunxi_monitor_composite_pal_nc: + pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0"; + break; + } + + /* Find a prefilled simpefb node, matching out pipeline config */ + offset = fdt_node_offset_by_compatible(blob, -1, + "allwinner,simple-framebuffer"); + while (offset >= 0) { + ret = fdt_stringlist_search(blob, offset, "allwinner,pipeline", + pipeline); + if (ret == 0) + break; + offset = fdt_node_offset_by_compatible(blob, offset, + "allwinner,simple-framebuffer"); + } + if (offset < 0) { + eprintf("Cannot setup simplefb: node not found\n"); + return 0; /* Keep older kernels working */ + } + + /* + * Do not report the framebuffer as free RAM to the OS, note we cannot + * use fdt_add_mem_rsv() here, because then it is still seen as RAM, + * and e.g. Linux refuses to iomap RAM on ARM, see: + * linux/arch/arm/mm/ioremap.c around line 301. + */ + start = gd->bd->bi_dram[0].start; + size = gd->bd->bi_dram[0].size - sunxi_display.fb_size; + ret = fdt_fixup_memory_banks(blob, &start, &size, 1); + if (ret) { + eprintf("Cannot setup simplefb: Error reserving memory\n"); + return ret; + } + + ret = fdt_setup_simplefb_node(blob, offset, sunxi_display.fb_addr, + graphic_device->winSizeX, graphic_device->winSizeY, + graphic_device->plnSizeX, "x8r8g8b8"); + if (ret) + eprintf("Cannot setup simplefb: Error setting properties\n"); + + return ret; +} +#endif /* CONFIG_OF_BOARD_SETUP && CONFIG_VIDEO_DT_SIMPLEFB */ diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c deleted file mode 100644 index 6f8ee01c107..00000000000 --- a/drivers/video/sunxi_display.c +++ /dev/null @@ -1,1599 +0,0 @@ -/* - * Display driver for Allwinner SoCs. - * - * (C) Copyright 2013-2014 Luc Verhaegen - * (C) Copyright 2014-2015 Hans de Goede - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "videomodes.h" -#include "anx9804.h" -#include "hitachi_tx18d42vm_lcd.h" -#include "ssd2828.h" - -#ifdef CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW -#define PWM_ON 0 -#define PWM_OFF 1 -#else -#define PWM_ON 1 -#define PWM_OFF 0 -#endif - -DECLARE_GLOBAL_DATA_PTR; - -enum sunxi_monitor { - sunxi_monitor_none, - sunxi_monitor_dvi, - sunxi_monitor_hdmi, - sunxi_monitor_lcd, - sunxi_monitor_vga, - sunxi_monitor_composite_pal, - sunxi_monitor_composite_ntsc, - sunxi_monitor_composite_pal_m, - sunxi_monitor_composite_pal_nc, -}; -#define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc - -struct sunxi_display { - GraphicDevice graphic_device; - enum sunxi_monitor monitor; - unsigned int depth; - unsigned int fb_addr; - unsigned int fb_size; -} sunxi_display; - -const struct ctfb_res_modes composite_video_modes[2] = { - /* x y hz pixclk ps/kHz le ri up lo hs vs s vmode */ - { 720, 576, 50, 37037, 27000, 137, 5, 20, 27, 2, 2, 0, FB_VMODE_INTERLACED }, - { 720, 480, 60, 37037, 27000, 116, 20, 16, 27, 2, 2, 0, FB_VMODE_INTERLACED }, -}; - -#ifdef CONFIG_VIDEO_HDMI - -/* - * Wait up to 200ms for value to be set in given part of reg. - */ -static int await_completion(u32 *reg, u32 mask, u32 val) -{ - unsigned long tmo = timer_get_us() + 200000; - - while ((readl(reg) & mask) != val) { - if (timer_get_us() > tmo) { - printf("DDC: timeout reading EDID\n"); - return -ETIME; - } - } - return 0; -} - -static int sunxi_hdmi_hpd_detect(int hpd_delay) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - struct sunxi_hdmi_reg * const hdmi = - (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; - unsigned long tmo = timer_get_us() + hpd_delay * 1000; - - /* Set pll3 to 300MHz */ - clock_set_pll3(300000000); - - /* Set hdmi parent to pll3 */ - clrsetbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_PLL_MASK, - CCM_HDMI_CTRL_PLL3); - - /* Set ahb gating to pass */ -#ifdef CONFIG_SUNXI_GEN_SUN6I - setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI); -#endif - setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI); - - /* Clock on */ - setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE); - - writel(SUNXI_HDMI_CTRL_ENABLE, &hdmi->ctrl); - writel(SUNXI_HDMI_PAD_CTRL0_HDP, &hdmi->pad_ctrl0); - - while (timer_get_us() < tmo) { - if (readl(&hdmi->hpd) & SUNXI_HDMI_HPD_DETECT) - return 1; - } - - return 0; -} - -static void sunxi_hdmi_shutdown(void) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - struct sunxi_hdmi_reg * const hdmi = - (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; - - clrbits_le32(&hdmi->ctrl, SUNXI_HDMI_CTRL_ENABLE); - clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE); - clrbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI); -#ifdef CONFIG_SUNXI_GEN_SUN6I - clrbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI); -#endif - clock_set_pll3(0); -} - -static int sunxi_hdmi_ddc_do_command(u32 cmnd, int offset, int n) -{ - struct sunxi_hdmi_reg * const hdmi = - (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; - - setbits_le32(&hdmi->ddc_fifo_ctrl, SUNXI_HDMI_DDC_FIFO_CTRL_CLEAR); - writel(SUNXI_HMDI_DDC_ADDR_EDDC_SEGMENT(offset >> 8) | - SUNXI_HMDI_DDC_ADDR_EDDC_ADDR | - SUNXI_HMDI_DDC_ADDR_OFFSET(offset) | - SUNXI_HMDI_DDC_ADDR_SLAVE_ADDR, &hdmi->ddc_addr); -#ifndef CONFIG_MACH_SUN6I - writel(n, &hdmi->ddc_byte_count); - writel(cmnd, &hdmi->ddc_cmnd); -#else - writel(n << 16 | cmnd, &hdmi->ddc_cmnd); -#endif - setbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_START); - - return await_completion(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_START, 0); -} - -static int sunxi_hdmi_ddc_read(int offset, u8 *buf, int count) -{ - struct sunxi_hdmi_reg * const hdmi = - (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; - int i, n; - - while (count > 0) { - if (count > 16) - n = 16; - else - n = count; - - if (sunxi_hdmi_ddc_do_command( - SUNXI_HDMI_DDC_CMND_EXPLICIT_EDDC_READ, - offset, n)) - return -ETIME; - - for (i = 0; i < n; i++) - *buf++ = readb(&hdmi->ddc_fifo_data); - - offset += n; - count -= n; - } - - return 0; -} - -static int sunxi_hdmi_edid_get_block(int block, u8 *buf) -{ - int r, retries = 2; - - do { - r = sunxi_hdmi_ddc_read(block * 128, buf, 128); - if (r) - continue; - r = edid_check_checksum(buf); - if (r) { - printf("EDID block %d: checksum error%s\n", - block, retries ? ", retrying" : ""); - } - } while (r && retries--); - - return r; -} - -static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) -{ - struct edid1_info edid1; - struct edid_cea861_info cea681[4]; - struct edid_detailed_timing *t = - (struct edid_detailed_timing *)edid1.monitor_details.timing; - struct sunxi_hdmi_reg * const hdmi = - (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - int i, r, ext_blocks = 0; - - /* SUNXI_HDMI_CTRL_ENABLE & PAD_CTRL0 are already set by hpd_detect */ - writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE, - &hdmi->pad_ctrl1); - writel(SUNXI_HDMI_PLL_CTRL | SUNXI_HDMI_PLL_CTRL_DIV(15), - &hdmi->pll_ctrl); - writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0); - - /* Reset i2c controller */ - setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE); - writel(SUNXI_HMDI_DDC_CTRL_ENABLE | - SUNXI_HMDI_DDC_CTRL_SDA_ENABLE | - SUNXI_HMDI_DDC_CTRL_SCL_ENABLE | - SUNXI_HMDI_DDC_CTRL_RESET, &hdmi->ddc_ctrl); - if (await_completion(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_RESET, 0)) - return -EIO; - - writel(SUNXI_HDMI_DDC_CLOCK, &hdmi->ddc_clock); -#ifndef CONFIG_MACH_SUN6I - writel(SUNXI_HMDI_DDC_LINE_CTRL_SDA_ENABLE | - SUNXI_HMDI_DDC_LINE_CTRL_SCL_ENABLE, &hdmi->ddc_line_ctrl); -#endif - - r = sunxi_hdmi_edid_get_block(0, (u8 *)&edid1); - if (r == 0) { - r = edid_check_info(&edid1); - if (r) { - printf("EDID: invalid EDID data\n"); - r = -EINVAL; - } - } - if (r == 0) { - ext_blocks = edid1.extension_flag; - if (ext_blocks > 4) - ext_blocks = 4; - for (i = 0; i < ext_blocks; i++) { - if (sunxi_hdmi_edid_get_block(1 + i, - (u8 *)&cea681[i]) != 0) { - ext_blocks = i; - break; - } - } - } - - /* Disable DDC engine, no longer needed */ - clrbits_le32(&hdmi->ddc_ctrl, SUNXI_HMDI_DDC_CTRL_ENABLE); - clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_DDC_GATE); - - if (r) - return r; - - /* We want version 1.3 or 1.2 with detailed timing info */ - if (edid1.version != 1 || (edid1.revision < 3 && - !EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(edid1))) { - printf("EDID: unsupported version %d.%d\n", - edid1.version, edid1.revision); - return -EINVAL; - } - - /* Take the first usable detailed timing */ - for (i = 0; i < 4; i++, t++) { - r = video_edid_dtd_to_ctfb_res_modes(t, mode); - if (r == 0) - break; - } - if (i == 4) { - printf("EDID: no usable detailed timing found\n"); - return -ENOENT; - } - - /* Check for basic audio support, if found enable hdmi output */ - sunxi_display.monitor = sunxi_monitor_dvi; - for (i = 0; i < ext_blocks; i++) { - if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG || - cea681[i].revision < 2) - continue; - - if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i])) - sunxi_display.monitor = sunxi_monitor_hdmi; - } - - return 0; -} - -#endif /* CONFIG_VIDEO_HDMI */ - -#ifdef CONFIG_MACH_SUN4I -/* - * Testing has shown that on sun4i the display backend engine does not have - * deep enough fifo-s causing flickering / tearing in full-hd mode due to - * fifo underruns. So on sun4i we use the display frontend engine to do the - * dma from memory, as the frontend does have deep enough fifo-s. - */ - -static const u32 sun4i_vert_coef[32] = { - 0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, - 0x00063efc, 0xff083dfc, 0x000a3bfb, 0xff0d39fb, - 0xff0f37fb, 0xff1136fa, 0xfe1433fb, 0xfe1631fb, - 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc, - 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd, - 0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff, - 0xfb370fff, 0xfb390dff, 0xfb3b0a00, 0xfc3d08ff, - 0xfc3e0600, 0xfd3f0400, 0xfe3f0300, 0xff400100, -}; - -static const u32 sun4i_horz_coef[64] = { - 0x40000000, 0x00000000, 0x40fe0000, 0x0000ff03, - 0x3ffd0000, 0x0000ff05, 0x3ffc0000, 0x0000ff06, - 0x3efb0000, 0x0000ff08, 0x3dfb0000, 0x0000ff09, - 0x3bfa0000, 0x0000fe0d, 0x39fa0000, 0x0000fe0f, - 0x38fa0000, 0x0000fe10, 0x36fa0000, 0x0000fe12, - 0x33fa0000, 0x0000fd16, 0x31fa0000, 0x0000fd18, - 0x2ffa0000, 0x0000fd1a, 0x2cfa0000, 0x0000fc1e, - 0x29fa0000, 0x0000fc21, 0x27fb0000, 0x0000fb23, - 0x24fb0000, 0x0000fb26, 0x21fb0000, 0x0000fb29, - 0x1ffc0000, 0x0000fa2b, 0x1cfc0000, 0x0000fa2e, - 0x19fd0000, 0x0000fa30, 0x16fd0000, 0x0000fa33, - 0x14fd0000, 0x0000fa35, 0x11fe0000, 0x0000fa37, - 0x0ffe0000, 0x0000fa39, 0x0dfe0000, 0x0000fa3b, - 0x0afe0000, 0x0000fa3e, 0x08ff0000, 0x0000fb3e, - 0x06ff0000, 0x0000fb40, 0x05ff0000, 0x0000fc40, - 0x03ff0000, 0x0000fd41, 0x01ff0000, 0x0000fe42, -}; - -static void sunxi_frontend_init(void) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - struct sunxi_de_fe_reg * const de_fe = - (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE; - int i; - - /* Clocks on */ - setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_FE0); - setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_FE0); - clock_set_de_mod_clock(&ccm->fe0_clk_cfg, 300000000); - - setbits_le32(&de_fe->enable, SUNXI_DE_FE_ENABLE_EN); - - for (i = 0; i < 32; i++) { - writel(sun4i_horz_coef[2 * i], &de_fe->ch0_horzcoef0[i]); - writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch0_horzcoef1[i]); - writel(sun4i_vert_coef[i], &de_fe->ch0_vertcoef[i]); - writel(sun4i_horz_coef[2 * i], &de_fe->ch1_horzcoef0[i]); - writel(sun4i_horz_coef[2 * i + 1], &de_fe->ch1_horzcoef1[i]); - writel(sun4i_vert_coef[i], &de_fe->ch1_vertcoef[i]); - } - - setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_COEF_RDY); -} - -static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode, - unsigned int address) -{ - struct sunxi_de_fe_reg * const de_fe = - (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE; - - setbits_le32(&de_fe->bypass, SUNXI_DE_FE_BYPASS_CSC_BYPASS); - writel(CONFIG_SYS_SDRAM_BASE + address, &de_fe->ch0_addr); - writel(mode->xres * 4, &de_fe->ch0_stride); - writel(SUNXI_DE_FE_INPUT_FMT_ARGB8888, &de_fe->input_fmt); - writel(SUNXI_DE_FE_OUTPUT_FMT_ARGB8888, &de_fe->output_fmt); - - writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres), - &de_fe->ch0_insize); - writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres), - &de_fe->ch0_outsize); - writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_horzfact); - writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch0_vertfact); - - writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres), - &de_fe->ch1_insize); - writel(SUNXI_DE_FE_HEIGHT(mode->yres) | SUNXI_DE_FE_WIDTH(mode->xres), - &de_fe->ch1_outsize); - writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_horzfact); - writel(SUNXI_DE_FE_FACTOR_INT(1), &de_fe->ch1_vertfact); - - setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_REG_RDY); -} - -static void sunxi_frontend_enable(void) -{ - struct sunxi_de_fe_reg * const de_fe = - (struct sunxi_de_fe_reg *)SUNXI_DE_FE0_BASE; - - setbits_le32(&de_fe->frame_ctrl, SUNXI_DE_FE_FRAME_CTRL_FRM_START); -} -#else -static void sunxi_frontend_init(void) {} -static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode, - unsigned int address) {} -static void sunxi_frontend_enable(void) {} -#endif - -static bool sunxi_is_composite(void) -{ - switch (sunxi_display.monitor) { - case sunxi_monitor_none: - case sunxi_monitor_dvi: - case sunxi_monitor_hdmi: - case sunxi_monitor_lcd: - case sunxi_monitor_vga: - return false; - case sunxi_monitor_composite_pal: - case sunxi_monitor_composite_ntsc: - case sunxi_monitor_composite_pal_m: - case sunxi_monitor_composite_pal_nc: - return true; - } - - return false; /* Never reached */ -} - -/* - * This is the entity that mixes and matches the different layers and inputs. - * Allwinner calls it the back-end, but i like composer better. - */ -static void sunxi_composer_init(void) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - struct sunxi_de_be_reg * const de_be = - (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE; - int i; - - sunxi_frontend_init(); - -#ifdef CONFIG_SUNXI_GEN_SUN6I - /* Reset off */ - setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE_BE0); -#endif - - /* Clocks on */ - setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE_BE0); -#ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */ - setbits_le32(&ccm->dram_clk_gate, 1 << CCM_DRAM_GATE_OFFSET_DE_BE0); -#endif - clock_set_de_mod_clock(&ccm->be0_clk_cfg, 300000000); - - /* Engine bug, clear registers after reset */ - for (i = 0x0800; i < 0x1000; i += 4) - writel(0, SUNXI_DE_BE0_BASE + i); - - setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_ENABLE); -} - -static u32 sunxi_rgb2yuv_coef[12] = { - 0x00000107, 0x00000204, 0x00000064, 0x00000108, - 0x00003f69, 0x00003ed6, 0x000001c1, 0x00000808, - 0x000001c1, 0x00003e88, 0x00003fb8, 0x00000808 -}; - -static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode, - unsigned int address) -{ - struct sunxi_de_be_reg * const de_be = - (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE; - int i; - - sunxi_frontend_mode_set(mode, address); - - writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres), - &de_be->disp_size); - writel(SUNXI_DE_BE_HEIGHT(mode->yres) | SUNXI_DE_BE_WIDTH(mode->xres), - &de_be->layer0_size); -#ifndef CONFIG_MACH_SUN4I /* On sun4i the frontend does the dma */ - writel(SUNXI_DE_BE_LAYER_STRIDE(mode->xres), &de_be->layer0_stride); - writel(address << 3, &de_be->layer0_addr_low32b); - writel(address >> 29, &de_be->layer0_addr_high4b); -#else - writel(SUNXI_DE_BE_LAYER_ATTR0_SRC_FE0, &de_be->layer0_attr0_ctrl); -#endif - writel(SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888, &de_be->layer0_attr1_ctrl); - - setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_LAYER0_ENABLE); - if (mode->vmode == FB_VMODE_INTERLACED) - setbits_le32(&de_be->mode, -#ifndef CONFIG_MACH_SUN5I - SUNXI_DE_BE_MODE_DEFLICKER_ENABLE | -#endif - SUNXI_DE_BE_MODE_INTERLACE_ENABLE); - - if (sunxi_is_composite()) { - writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE, - &de_be->output_color_ctrl); - for (i = 0; i < 12; i++) - writel(sunxi_rgb2yuv_coef[i], - &de_be->output_color_coef[i]); - } -} - -static void sunxi_composer_enable(void) -{ - struct sunxi_de_be_reg * const de_be = - (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE; - - sunxi_frontend_enable(); - - setbits_le32(&de_be->reg_ctrl, SUNXI_DE_BE_REG_CTRL_LOAD_REGS); - setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_START); -} - -/* - * LCDC, what allwinner calls a CRTC, so timing controller and serializer. - */ -static void sunxi_lcdc_pll_set(int tcon, int dotclock, - int *clk_div, int *clk_double) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - int value, n, m, min_m, max_m, diff; - int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF; - int best_double = 0; - bool use_mipi_pll = false; - - if (tcon == 0) { -#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL - min_m = 6; - max_m = 127; -#endif -#ifdef CONFIG_VIDEO_LCD_IF_LVDS - min_m = max_m = 7; -#endif - } else { - min_m = 1; - max_m = 15; - } - - /* - * Find the lowest divider resulting in a matching clock, if there - * is no match, pick the closest lower clock, as monitors tend to - * not sync to higher frequencies. - */ - for (m = min_m; m <= max_m; m++) { - n = (m * dotclock) / 3000; - - if ((n >= 9) && (n <= 127)) { - value = (3000 * n) / m; - diff = dotclock - value; - if (diff < best_diff) { - best_diff = diff; - best_m = m; - best_n = n; - best_double = 0; - } - } - - /* These are just duplicates */ - if (!(m & 1)) - continue; - - n = (m * dotclock) / 6000; - if ((n >= 9) && (n <= 127)) { - value = (6000 * n) / m; - diff = dotclock - value; - if (diff < best_diff) { - best_diff = diff; - best_m = m; - best_n = n; - best_double = 1; - } - } - } - -#ifdef CONFIG_MACH_SUN6I - /* - * Use the MIPI pll if we've been unable to find any matching setting - * for PLL3, this happens with high dotclocks because of min_m = 6. - */ - if (tcon == 0 && best_n == 0) { - use_mipi_pll = true; - best_m = 6; /* Minimum m for tcon0 */ - } - - if (use_mipi_pll) { - clock_set_pll3(297000000); /* Fix the video pll at 297 MHz */ - clock_set_mipi_pll(best_m * dotclock * 1000); - debug("dotclock: %dkHz = %dkHz via mipi pll\n", - dotclock, clock_get_mipi_pll() / best_m / 1000); - } else -#endif - { - clock_set_pll3(best_n * 3000000); - debug("dotclock: %dkHz = %dkHz: (%d * 3MHz * %d) / %d\n", - dotclock, - (best_double + 1) * clock_get_pll3() / best_m / 1000, - best_double + 1, best_n, best_m); - } - - if (tcon == 0) { - u32 pll; - - if (use_mipi_pll) - pll = CCM_LCD_CH0_CTRL_MIPI_PLL; - else if (best_double) - pll = CCM_LCD_CH0_CTRL_PLL3_2X; - else - pll = CCM_LCD_CH0_CTRL_PLL3; - - writel(CCM_LCD_CH0_CTRL_GATE | CCM_LCD_CH0_CTRL_RST | pll, - &ccm->lcd0_ch0_clk_cfg); - } else { - writel(CCM_LCD_CH1_CTRL_GATE | - (best_double ? CCM_LCD_CH1_CTRL_PLL3_2X : - CCM_LCD_CH1_CTRL_PLL3) | - CCM_LCD_CH1_CTRL_M(best_m), &ccm->lcd0_ch1_clk_cfg); - if (sunxi_is_composite()) - setbits_le32(&ccm->lcd0_ch1_clk_cfg, - CCM_LCD_CH1_CTRL_HALF_SCLK1); - } - - *clk_div = best_m; - *clk_double = best_double; -} - -static void sunxi_lcdc_init(void) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - struct sunxi_lcdc_reg * const lcdc = - (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; - - /* Reset off */ -#ifdef CONFIG_SUNXI_GEN_SUN6I - setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0); -#else - setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_RST); -#endif - - /* Clock on */ - setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0); -#ifdef CONFIG_VIDEO_LCD_IF_LVDS -#ifdef CONFIG_SUNXI_GEN_SUN6I - setbits_le32(&ccm->ahb_reset2_cfg, 1 << AHB_RESET_OFFSET_LVDS); -#else - setbits_le32(&ccm->lvds_clk_cfg, CCM_LVDS_CTRL_RST); -#endif -#endif - - /* Init lcdc */ - writel(0, &lcdc->ctrl); /* Disable tcon */ - writel(0, &lcdc->int0); /* Disable all interrupts */ - - /* Disable tcon0 dot clock */ - clrbits_le32(&lcdc->tcon0_dclk, SUNXI_LCDC_TCON0_DCLK_ENABLE); - - /* Set all io lines to tristate */ - writel(0xffffffff, &lcdc->tcon0_io_tristate); - writel(0xffffffff, &lcdc->tcon1_io_tristate); -} - -static void sunxi_lcdc_enable(void) -{ - struct sunxi_lcdc_reg * const lcdc = - (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; - - setbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE); -#ifdef CONFIG_VIDEO_LCD_IF_LVDS - setbits_le32(&lcdc->tcon0_lvds_intf, SUNXI_LCDC_TCON0_LVDS_INTF_ENABLE); - setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0); -#ifdef CONFIG_SUNXI_GEN_SUN6I - udelay(2); /* delay at least 1200 ns */ - setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_EN_MB); - udelay(2); /* delay at least 1200 ns */ - setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVC); - if (sunxi_display.depth == 18) - setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0x7)); - else - setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_DRVD(0xf)); -#else - setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE); - udelay(2); /* delay at least 1200 ns */ - setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT1); - udelay(1); /* delay at least 120 ns */ - setbits_le32(&lcdc->lvds_ana1, SUNXI_LCDC_LVDS_ANA1_INIT2); - setbits_le32(&lcdc->lvds_ana0, SUNXI_LCDC_LVDS_ANA0_UPDATE); -#endif -#endif -} - -static void sunxi_lcdc_panel_enable(void) -{ - int pin, reset_pin; - - /* - * Start with backlight disabled to avoid the screen flashing to - * white while the lcd inits. - */ - pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN); - if (pin >= 0) { - gpio_request(pin, "lcd_backlight_enable"); - gpio_direction_output(pin, 0); - } - - pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM); - if (pin >= 0) { - gpio_request(pin, "lcd_backlight_pwm"); - gpio_direction_output(pin, PWM_OFF); - } - - reset_pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_RESET); - if (reset_pin >= 0) { - gpio_request(reset_pin, "lcd_reset"); - gpio_direction_output(reset_pin, 0); /* Assert reset */ - } - - /* Give the backlight some time to turn off and power up the panel. */ - mdelay(40); - pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_POWER); - if (pin >= 0) { - gpio_request(pin, "lcd_power"); - gpio_direction_output(pin, 1); - } - - if (reset_pin >= 0) - gpio_direction_output(reset_pin, 1); /* De-assert reset */ -} - -static void sunxi_lcdc_backlight_enable(void) -{ - int pin; - - /* - * We want to have scanned out at least one frame before enabling the - * backlight to avoid the screen flashing to white when we enable it. - */ - mdelay(40); - - pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_EN); - if (pin >= 0) - gpio_direction_output(pin, 1); - - pin = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_BL_PWM); -#ifdef SUNXI_PWM_PIN0 - if (pin == SUNXI_PWM_PIN0) { - writel(SUNXI_PWM_CTRL_POLARITY0(PWM_ON) | - SUNXI_PWM_CTRL_ENABLE0 | - SUNXI_PWM_CTRL_PRESCALE0(0xf), SUNXI_PWM_CTRL_REG); - writel(SUNXI_PWM_PERIOD_80PCT, SUNXI_PWM_CH0_PERIOD); - sunxi_gpio_set_cfgpin(pin, SUNXI_PWM_MUX); - return; - } -#endif - if (pin >= 0) - gpio_direction_output(pin, PWM_ON); -} - -static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode, int tcon) -{ - int delay; - - delay = mode->lower_margin + mode->vsync_len + mode->upper_margin; - if (mode->vmode == FB_VMODE_INTERLACED) - delay /= 2; - if (tcon == 1) - delay -= 2; - - return (delay > 30) ? 30 : delay; -} - -static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode, - bool for_ext_vga_dac) -{ - struct sunxi_lcdc_reg * const lcdc = - (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; - int bp, clk_delay, clk_div, clk_double, pin, total, val; - -#if defined CONFIG_MACH_SUN8I && defined CONFIG_VIDEO_LCD_IF_LVDS - for (pin = SUNXI_GPD(18); pin <= SUNXI_GPD(27); pin++) { -#else - for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++) { -#endif -#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL - sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0); -#endif -#ifdef CONFIG_VIDEO_LCD_IF_LVDS - sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0); -#endif -#ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804 - sunxi_gpio_set_drv(pin, 3); -#endif - } - - sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double); - - /* Use tcon0 */ - clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK, - SUNXI_LCDC_CTRL_IO_MAP_TCON0); - - clk_delay = sunxi_lcdc_get_clk_delay(mode, 0); - writel(SUNXI_LCDC_TCON0_CTRL_ENABLE | - SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl); - - writel(SUNXI_LCDC_TCON0_DCLK_ENABLE | - SUNXI_LCDC_TCON0_DCLK_DIV(clk_div), &lcdc->tcon0_dclk); - - writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(mode->yres), - &lcdc->tcon0_timing_active); - - bp = mode->hsync_len + mode->left_margin; - total = mode->xres + mode->right_margin + bp; - writel(SUNXI_LCDC_TCON0_TIMING_H_TOTAL(total) | - SUNXI_LCDC_TCON0_TIMING_H_BP(bp), &lcdc->tcon0_timing_h); - - bp = mode->vsync_len + mode->upper_margin; - total = mode->yres + mode->lower_margin + bp; - writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) | - SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v); - -#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL - writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len), - &lcdc->tcon0_timing_sync); - - writel(0, &lcdc->tcon0_hv_intf); - writel(0, &lcdc->tcon0_cpu_intf); -#endif -#ifdef CONFIG_VIDEO_LCD_IF_LVDS - val = (sunxi_display.depth == 18) ? 1 : 0; - writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val) | - SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0, &lcdc->tcon0_lvds_intf); -#endif - - if (sunxi_display.depth == 18 || sunxi_display.depth == 16) { - writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[0]); - writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[1]); - writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[2]); - writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[3]); - writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[4]); - writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[5]); - writel(SUNXI_LCDC_TCON0_FRM_TAB0, &lcdc->tcon0_frm_table[0]); - writel(SUNXI_LCDC_TCON0_FRM_TAB1, &lcdc->tcon0_frm_table[1]); - writel(SUNXI_LCDC_TCON0_FRM_TAB2, &lcdc->tcon0_frm_table[2]); - writel(SUNXI_LCDC_TCON0_FRM_TAB3, &lcdc->tcon0_frm_table[3]); - writel(((sunxi_display.depth == 18) ? - SUNXI_LCDC_TCON0_FRM_CTRL_RGB666 : - SUNXI_LCDC_TCON0_FRM_CTRL_RGB565), - &lcdc->tcon0_frm_ctrl); - } - - val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(CONFIG_VIDEO_LCD_DCLK_PHASE); - if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT)) - val |= SUNXI_LCDC_TCON_HSYNC_MASK; - if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) - val |= SUNXI_LCDC_TCON_VSYNC_MASK; - -#ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH - if (for_ext_vga_dac) - val = 0; -#endif - writel(val, &lcdc->tcon0_io_polarity); - - writel(0, &lcdc->tcon0_io_tristate); -} - -#if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE -static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode, - int *clk_div, int *clk_double, - bool use_portd_hvsync) -{ - struct sunxi_lcdc_reg * const lcdc = - (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; - int bp, clk_delay, total, val, yres; - - /* Use tcon1 */ - clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK, - SUNXI_LCDC_CTRL_IO_MAP_TCON1); - - clk_delay = sunxi_lcdc_get_clk_delay(mode, 1); - writel(SUNXI_LCDC_TCON1_CTRL_ENABLE | - ((mode->vmode == FB_VMODE_INTERLACED) ? - SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE : 0) | - SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon1_ctrl); - - yres = mode->yres; - if (mode->vmode == FB_VMODE_INTERLACED) - yres /= 2; - writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), - &lcdc->tcon1_timing_source); - writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), - &lcdc->tcon1_timing_scale); - writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), - &lcdc->tcon1_timing_out); - - bp = mode->hsync_len + mode->left_margin; - total = mode->xres + mode->right_margin + bp; - writel(SUNXI_LCDC_TCON1_TIMING_H_TOTAL(total) | - SUNXI_LCDC_TCON1_TIMING_H_BP(bp), &lcdc->tcon1_timing_h); - - bp = mode->vsync_len + mode->upper_margin; - total = mode->yres + mode->lower_margin + bp; - if (mode->vmode == FB_VMODE_NONINTERLACED) - total *= 2; - writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(total) | - SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc->tcon1_timing_v); - - writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len), - &lcdc->tcon1_timing_sync); - - if (use_portd_hvsync) { - sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0); - sunxi_gpio_set_cfgpin(SUNXI_GPD(27), SUNXI_GPD_LCD0); - - val = 0; - if (mode->sync & FB_SYNC_HOR_HIGH_ACT) - val |= SUNXI_LCDC_TCON_HSYNC_MASK; - if (mode->sync & FB_SYNC_VERT_HIGH_ACT) - val |= SUNXI_LCDC_TCON_VSYNC_MASK; - writel(val, &lcdc->tcon1_io_polarity); - - clrbits_le32(&lcdc->tcon1_io_tristate, - SUNXI_LCDC_TCON_VSYNC_MASK | - SUNXI_LCDC_TCON_HSYNC_MASK); - } - -#ifdef CONFIG_MACH_SUN5I - if (sunxi_is_composite()) - clrsetbits_le32(&lcdc->mux_ctrl, SUNXI_LCDC_MUX_CTRL_SRC0_MASK, - SUNXI_LCDC_MUX_CTRL_SRC0(1)); -#endif - - sunxi_lcdc_pll_set(1, mode->pixclock_khz, clk_div, clk_double); -} -#endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */ - -#ifdef CONFIG_VIDEO_HDMI - -static void sunxi_hdmi_setup_info_frames(const struct ctfb_res_modes *mode) -{ - struct sunxi_hdmi_reg * const hdmi = - (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; - u8 checksum = 0; - u8 avi_info_frame[17] = { - 0x82, 0x02, 0x0d, 0x00, 0x12, 0x00, 0x88, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00 - }; - u8 vendor_info_frame[19] = { - 0x81, 0x01, 0x06, 0x29, 0x03, 0x0c, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 - }; - int i; - - if (mode->pixclock_khz <= 27000) - avi_info_frame[5] = 0x40; /* SD-modes, ITU601 colorspace */ - else - avi_info_frame[5] = 0x80; /* HD-modes, ITU709 colorspace */ - - if (mode->xres * 100 / mode->yres < 156) - avi_info_frame[5] |= 0x18; /* 4 : 3 */ - else - avi_info_frame[5] |= 0x28; /* 16 : 9 */ - - for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++) - checksum += avi_info_frame[i]; - - avi_info_frame[3] = 0x100 - checksum; - - for (i = 0; i < ARRAY_SIZE(avi_info_frame); i++) - writeb(avi_info_frame[i], &hdmi->avi_info_frame[i]); - - writel(SUNXI_HDMI_QCP_PACKET0, &hdmi->qcp_packet0); - writel(SUNXI_HDMI_QCP_PACKET1, &hdmi->qcp_packet1); - - for (i = 0; i < ARRAY_SIZE(vendor_info_frame); i++) - writeb(vendor_info_frame[i], &hdmi->vendor_info_frame[i]); - - writel(SUNXI_HDMI_PKT_CTRL0, &hdmi->pkt_ctrl0); - writel(SUNXI_HDMI_PKT_CTRL1, &hdmi->pkt_ctrl1); - - setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_HDMI); -} - -static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode, - int clk_div, int clk_double) -{ - struct sunxi_hdmi_reg * const hdmi = - (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; - int x, y; - - /* Write clear interrupt status bits */ - writel(SUNXI_HDMI_IRQ_STATUS_BITS, &hdmi->irq); - - if (sunxi_display.monitor == sunxi_monitor_hdmi) - sunxi_hdmi_setup_info_frames(mode); - - /* Set input sync enable */ - writel(SUNXI_HDMI_UNKNOWN_INPUT_SYNC, &hdmi->unknown); - - /* Init various registers, select pll3 as clock source */ - writel(SUNXI_HDMI_VIDEO_POL_TX_CLK, &hdmi->video_polarity); - writel(SUNXI_HDMI_PAD_CTRL0_RUN, &hdmi->pad_ctrl0); - writel(SUNXI_HDMI_PAD_CTRL1, &hdmi->pad_ctrl1); - writel(SUNXI_HDMI_PLL_CTRL, &hdmi->pll_ctrl); - writel(SUNXI_HDMI_PLL_DBG0_PLL3, &hdmi->pll_dbg0); - - /* Setup clk div and doubler */ - clrsetbits_le32(&hdmi->pll_ctrl, SUNXI_HDMI_PLL_CTRL_DIV_MASK, - SUNXI_HDMI_PLL_CTRL_DIV(clk_div)); - if (!clk_double) - setbits_le32(&hdmi->pad_ctrl1, SUNXI_HDMI_PAD_CTRL1_HALVE); - - /* Setup timing registers */ - writel(SUNXI_HDMI_Y(mode->yres) | SUNXI_HDMI_X(mode->xres), - &hdmi->video_size); - - x = mode->hsync_len + mode->left_margin; - y = mode->vsync_len + mode->upper_margin; - writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_bp); - - x = mode->right_margin; - y = mode->lower_margin; - writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_fp); - - x = mode->hsync_len; - y = mode->vsync_len; - writel(SUNXI_HDMI_Y(y) | SUNXI_HDMI_X(x), &hdmi->video_spw); - - if (mode->sync & FB_SYNC_HOR_HIGH_ACT) - setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_HOR); - - if (mode->sync & FB_SYNC_VERT_HIGH_ACT) - setbits_le32(&hdmi->video_polarity, SUNXI_HDMI_VIDEO_POL_VER); -} - -static void sunxi_hdmi_enable(void) -{ - struct sunxi_hdmi_reg * const hdmi = - (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; - - udelay(100); - setbits_le32(&hdmi->video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE); -} - -#endif /* CONFIG_VIDEO_HDMI */ - -#if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE - -static void sunxi_tvencoder_mode_set(void) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - struct sunxi_tve_reg * const tve = - (struct sunxi_tve_reg *)SUNXI_TVE0_BASE; - - /* Reset off */ - setbits_le32(&ccm->lcd0_ch0_clk_cfg, CCM_LCD_CH0_CTRL_TVE_RST); - /* Clock on */ - setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0); - - switch (sunxi_display.monitor) { - case sunxi_monitor_vga: - writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | - SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | - SUNXI_TVE_GCTRL_DAC_INPUT(2, 3), &tve->gctrl); - writel(SUNXI_TVE_CFG0_VGA, &tve->cfg0); - writel(SUNXI_TVE_DAC_CFG0_VGA, &tve->dac_cfg0); - writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1); - break; - case sunxi_monitor_composite_pal_nc: - writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq); - /* Fall through */ - case sunxi_monitor_composite_pal: - writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | - SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | - SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) | - SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl); - writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0); - writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0); - writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter); - writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num); - writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num); - writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL, &tve->blank_black_level); - writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1); - writel(SUNXI_TVE_CBR_LEVEL_PAL, &tve->cbr_level); - writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width); - writel(SUNXI_TVE_UNKNOWN2_PAL, &tve->unknown2); - writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num); - writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain); - writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width); - writel(SUNXI_TVE_RESYNC_NUM_PAL, &tve->resync_num); - writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para); - break; - case sunxi_monitor_composite_pal_m: - writel(SUNXI_TVE_CHROMA_FREQ_PAL_M, &tve->chroma_freq); - writel(SUNXI_TVE_COLOR_BURST_PAL_M, &tve->color_burst); - /* Fall through */ - case sunxi_monitor_composite_ntsc: - writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) | - SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) | - SUNXI_TVE_GCTRL_DAC_INPUT(2, 3) | - SUNXI_TVE_GCTRL_DAC_INPUT(3, 4), &tve->gctrl); - writel(SUNXI_TVE_CFG0_NTSC, &tve->cfg0); - writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0); - writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter); - writel(SUNXI_TVE_PORCH_NUM_NTSC, &tve->porch_num); - writel(SUNXI_TVE_LINE_NUM_NTSC, &tve->line_num); - writel(SUNXI_TVE_BLANK_BLACK_LEVEL_NTSC, &tve->blank_black_level); - writel(SUNXI_TVE_UNKNOWN1_COMPOSITE, &tve->unknown1); - writel(SUNXI_TVE_CBR_LEVEL_NTSC, &tve->cbr_level); - writel(SUNXI_TVE_BURST_PHASE_NTSC, &tve->burst_phase); - writel(SUNXI_TVE_BURST_WIDTH_COMPOSITE, &tve->burst_width); - writel(SUNXI_TVE_UNKNOWN2_NTSC, &tve->unknown2); - writel(SUNXI_TVE_SYNC_VBI_LEVEL_NTSC, &tve->sync_vbi_level); - writel(SUNXI_TVE_ACTIVE_NUM_COMPOSITE, &tve->active_num); - writel(SUNXI_TVE_CHROMA_BW_GAIN_COMP, &tve->chroma_bw_gain); - writel(SUNXI_TVE_NOTCH_WIDTH_COMPOSITE, &tve->notch_width); - writel(SUNXI_TVE_RESYNC_NUM_NTSC, &tve->resync_num); - writel(SUNXI_TVE_SLAVE_PARA_COMPOSITE, &tve->slave_para); - break; - case sunxi_monitor_none: - case sunxi_monitor_dvi: - case sunxi_monitor_hdmi: - case sunxi_monitor_lcd: - break; - } -} - -static void sunxi_tvencoder_enable(void) -{ - struct sunxi_tve_reg * const tve = - (struct sunxi_tve_reg *)SUNXI_TVE0_BASE; - - setbits_le32(&tve->gctrl, SUNXI_TVE_GCTRL_ENABLE); -} - -#endif /* CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE */ - -static void sunxi_drc_init(void) -{ -#ifdef CONFIG_SUNXI_GEN_SUN6I - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - - /* On sun6i the drc must be clocked even when in pass-through mode */ -#ifdef CONFIG_MACH_SUN8I_A33 - setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_SAT); -#endif - setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DRC0); - clock_set_de_mod_clock(&ccm->iep_drc0_clk_cfg, 300000000); -#endif -} - -#ifdef CONFIG_VIDEO_VGA_VIA_LCD -static void sunxi_vga_external_dac_enable(void) -{ - int pin; - - pin = sunxi_name_to_gpio(CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN); - if (pin >= 0) { - gpio_request(pin, "vga_enable"); - gpio_direction_output(pin, 1); - } -} -#endif /* CONFIG_VIDEO_VGA_VIA_LCD */ - -#ifdef CONFIG_VIDEO_LCD_SSD2828 -static int sunxi_ssd2828_init(const struct ctfb_res_modes *mode) -{ - struct ssd2828_config cfg = { - .csx_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_CS), - .sck_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_SCLK), - .sdi_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MOSI), - .sdo_pin = name_to_gpio(CONFIG_VIDEO_LCD_SPI_MISO), - .reset_pin = name_to_gpio(CONFIG_VIDEO_LCD_SSD2828_RESET), - .ssd2828_tx_clk_khz = CONFIG_VIDEO_LCD_SSD2828_TX_CLK * 1000, - .ssd2828_color_depth = 24, -#ifdef CONFIG_VIDEO_LCD_PANEL_MIPI_4_LANE_513_MBPS_VIA_SSD2828 - .mipi_dsi_number_of_data_lanes = 4, - .mipi_dsi_bitrate_per_data_lane_mbps = 513, - .mipi_dsi_delay_after_exit_sleep_mode_ms = 100, - .mipi_dsi_delay_after_set_display_on_ms = 200 -#else -#error MIPI LCD panel needs configuration parameters -#endif - }; - - if (cfg.csx_pin == -1 || cfg.sck_pin == -1 || cfg.sdi_pin == -1) { - printf("SSD2828: SPI pins are not properly configured\n"); - return 1; - } - if (cfg.reset_pin == -1) { - printf("SSD2828: Reset pin is not properly configured\n"); - return 1; - } - - return ssd2828_init(&cfg, mode); -} -#endif /* CONFIG_VIDEO_LCD_SSD2828 */ - -static void sunxi_engines_init(void) -{ - sunxi_composer_init(); - sunxi_lcdc_init(); - sunxi_drc_init(); -} - -static void sunxi_mode_set(const struct ctfb_res_modes *mode, - unsigned int address) -{ - int __maybe_unused clk_div, clk_double; - - switch (sunxi_display.monitor) { - case sunxi_monitor_none: - break; - case sunxi_monitor_dvi: - case sunxi_monitor_hdmi: -#ifdef CONFIG_VIDEO_HDMI - sunxi_composer_mode_set(mode, address); - sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0); - sunxi_hdmi_mode_set(mode, clk_div, clk_double); - sunxi_composer_enable(); - sunxi_lcdc_enable(); - sunxi_hdmi_enable(); -#endif - break; - case sunxi_monitor_lcd: - sunxi_lcdc_panel_enable(); - if (IS_ENABLED(CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804)) { - /* - * The anx9804 needs 1.8V from eldo3, we do this here - * and not via CONFIG_AXP_ELDO3_VOLT from board_init() - * to avoid turning this on when using hdmi output. - */ - axp_set_eldo(3, 1800); - anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4, - ANX9804_DATA_RATE_1620M, - sunxi_display.depth); - } - if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) { - mdelay(50); /* Wait for lcd controller power on */ - hitachi_tx18d42vm_init(); - } - if (IS_ENABLED(CONFIG_VIDEO_LCD_TL059WV5C0)) { - unsigned int orig_i2c_bus = i2c_get_bus_num(); - i2c_set_bus_num(CONFIG_VIDEO_LCD_I2C_BUS); - i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */ - i2c_set_bus_num(orig_i2c_bus); - } - sunxi_composer_mode_set(mode, address); - sunxi_lcdc_tcon0_mode_set(mode, false); - sunxi_composer_enable(); - sunxi_lcdc_enable(); -#ifdef CONFIG_VIDEO_LCD_SSD2828 - sunxi_ssd2828_init(mode); -#endif - sunxi_lcdc_backlight_enable(); - break; - case sunxi_monitor_vga: -#ifdef CONFIG_VIDEO_VGA - sunxi_composer_mode_set(mode, address); - sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1); - sunxi_tvencoder_mode_set(); - sunxi_composer_enable(); - sunxi_lcdc_enable(); - sunxi_tvencoder_enable(); -#elif defined CONFIG_VIDEO_VGA_VIA_LCD - sunxi_composer_mode_set(mode, address); - sunxi_lcdc_tcon0_mode_set(mode, true); - sunxi_composer_enable(); - sunxi_lcdc_enable(); - sunxi_vga_external_dac_enable(); -#endif - break; - case sunxi_monitor_composite_pal: - case sunxi_monitor_composite_ntsc: - case sunxi_monitor_composite_pal_m: - case sunxi_monitor_composite_pal_nc: -#ifdef CONFIG_VIDEO_COMPOSITE - sunxi_composer_mode_set(mode, address); - sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0); - sunxi_tvencoder_mode_set(); - sunxi_composer_enable(); - sunxi_lcdc_enable(); - sunxi_tvencoder_enable(); -#endif - break; - } -} - -static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor) -{ - switch (monitor) { - case sunxi_monitor_none: return "none"; - case sunxi_monitor_dvi: return "dvi"; - case sunxi_monitor_hdmi: return "hdmi"; - case sunxi_monitor_lcd: return "lcd"; - case sunxi_monitor_vga: return "vga"; - case sunxi_monitor_composite_pal: return "composite-pal"; - case sunxi_monitor_composite_ntsc: return "composite-ntsc"; - case sunxi_monitor_composite_pal_m: return "composite-pal-m"; - case sunxi_monitor_composite_pal_nc: return "composite-pal-nc"; - } - return NULL; /* never reached */ -} - -ulong board_get_usable_ram_top(ulong total_size) -{ - return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE; -} - -static bool sunxi_has_hdmi(void) -{ -#ifdef CONFIG_VIDEO_HDMI - return true; -#else - return false; -#endif -} - -static bool sunxi_has_lcd(void) -{ - char *lcd_mode = CONFIG_VIDEO_LCD_MODE; - - return lcd_mode[0] != 0; -} - -static bool sunxi_has_vga(void) -{ -#if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_VGA_VIA_LCD - return true; -#else - return false; -#endif -} - -static bool sunxi_has_composite(void) -{ -#ifdef CONFIG_VIDEO_COMPOSITE - return true; -#else - return false; -#endif -} - -static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi) -{ - if (allow_hdmi && sunxi_has_hdmi()) - return sunxi_monitor_dvi; - else if (sunxi_has_lcd()) - return sunxi_monitor_lcd; - else if (sunxi_has_vga()) - return sunxi_monitor_vga; - else if (sunxi_has_composite()) - return sunxi_monitor_composite_pal; - else - return sunxi_monitor_none; -} - -void *video_hw_init(void) -{ - static GraphicDevice *graphic_device = &sunxi_display.graphic_device; - const struct ctfb_res_modes *mode; - struct ctfb_res_modes custom; - const char *options; -#ifdef CONFIG_VIDEO_HDMI - int ret, hpd, hpd_delay, edid; -#endif - int i, overscan_offset, overscan_x, overscan_y; - unsigned int fb_dma_addr; - char mon[16]; - char *lcd_mode = CONFIG_VIDEO_LCD_MODE; - - memset(&sunxi_display, 0, sizeof(struct sunxi_display)); - - video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, - &sunxi_display.depth, &options); -#ifdef CONFIG_VIDEO_HDMI - hpd = video_get_option_int(options, "hpd", 1); - hpd_delay = video_get_option_int(options, "hpd_delay", 500); - edid = video_get_option_int(options, "edid", 1); -#endif - overscan_x = video_get_option_int(options, "overscan_x", -1); - overscan_y = video_get_option_int(options, "overscan_y", -1); - sunxi_display.monitor = sunxi_get_default_mon(true); - video_get_option_string(options, "monitor", mon, sizeof(mon), - sunxi_get_mon_desc(sunxi_display.monitor)); - for (i = 0; i <= SUNXI_MONITOR_LAST; i++) { - if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) { - sunxi_display.monitor = i; - break; - } - } - if (i > SUNXI_MONITOR_LAST) - printf("Unknown monitor: '%s', falling back to '%s'\n", - mon, sunxi_get_mon_desc(sunxi_display.monitor)); - -#ifdef CONFIG_VIDEO_HDMI - /* If HDMI/DVI is selected do HPD & EDID, and handle fallback */ - if (sunxi_display.monitor == sunxi_monitor_dvi || - sunxi_display.monitor == sunxi_monitor_hdmi) { - /* Always call hdp_detect, as it also enables clocks, etc. */ - ret = sunxi_hdmi_hpd_detect(hpd_delay); - if (ret) { - printf("HDMI connected: "); - if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0) - mode = &custom; - } else if (hpd) { - sunxi_hdmi_shutdown(); - sunxi_display.monitor = sunxi_get_default_mon(false); - } /* else continue with hdmi/dvi without a cable connected */ - } -#endif - - switch (sunxi_display.monitor) { - case sunxi_monitor_none: - return NULL; - case sunxi_monitor_dvi: - case sunxi_monitor_hdmi: - if (!sunxi_has_hdmi()) { - printf("HDMI/DVI not supported on this board\n"); - sunxi_display.monitor = sunxi_monitor_none; - return NULL; - } - break; - case sunxi_monitor_lcd: - if (!sunxi_has_lcd()) { - printf("LCD not supported on this board\n"); - sunxi_display.monitor = sunxi_monitor_none; - return NULL; - } - sunxi_display.depth = video_get_params(&custom, lcd_mode); - mode = &custom; - break; - case sunxi_monitor_vga: - if (!sunxi_has_vga()) { - printf("VGA not supported on this board\n"); - sunxi_display.monitor = sunxi_monitor_none; - return NULL; - } - sunxi_display.depth = 18; - break; - case sunxi_monitor_composite_pal: - case sunxi_monitor_composite_ntsc: - case sunxi_monitor_composite_pal_m: - case sunxi_monitor_composite_pal_nc: - if (!sunxi_has_composite()) { - printf("Composite video not supported on this board\n"); - sunxi_display.monitor = sunxi_monitor_none; - return NULL; - } - if (sunxi_display.monitor == sunxi_monitor_composite_pal || - sunxi_display.monitor == sunxi_monitor_composite_pal_nc) - mode = &composite_video_modes[0]; - else - mode = &composite_video_modes[1]; - sunxi_display.depth = 24; - break; - } - - /* Yes these defaults are quite high, overscan on composite sucks... */ - if (overscan_x == -1) - overscan_x = sunxi_is_composite() ? 32 : 0; - if (overscan_y == -1) - overscan_y = sunxi_is_composite() ? 20 : 0; - - sunxi_display.fb_size = - (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff; - overscan_offset = (overscan_y * mode->xres + overscan_x) * 4; - /* We want to keep the fb_base for simplefb page aligned, where as - * the sunxi dma engines will happily accept an unaligned address. */ - if (overscan_offset) - sunxi_display.fb_size += 0x1000; - - if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) { - printf("Error need %dkB for fb, but only %dkB is reserved\n", - sunxi_display.fb_size >> 10, - CONFIG_SUNXI_MAX_FB_SIZE >> 10); - return NULL; - } - - printf("Setting up a %dx%d%s %s console (overscan %dx%d)\n", - mode->xres, mode->yres, - (mode->vmode == FB_VMODE_INTERLACED) ? "i" : "", - sunxi_get_mon_desc(sunxi_display.monitor), - overscan_x, overscan_y); - - gd->fb_base = gd->bd->bi_dram[0].start + - gd->bd->bi_dram[0].size - sunxi_display.fb_size; - sunxi_engines_init(); - - fb_dma_addr = gd->fb_base - CONFIG_SYS_SDRAM_BASE; - sunxi_display.fb_addr = gd->fb_base; - if (overscan_offset) { - fb_dma_addr += 0x1000 - (overscan_offset & 0xfff); - sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff; - memset((void *)gd->fb_base, 0, sunxi_display.fb_size); - flush_cache(gd->fb_base, sunxi_display.fb_size); - } - sunxi_mode_set(mode, fb_dma_addr); - - /* - * These are the only members of this structure that are used. All the - * others are driver specific. The pitch is stored in plnSizeX. - */ - graphic_device->frameAdrs = sunxi_display.fb_addr; - graphic_device->gdfIndex = GDF_32BIT_X888RGB; - graphic_device->gdfBytesPP = 4; - graphic_device->winSizeX = mode->xres - 2 * overscan_x; - graphic_device->winSizeY = mode->yres - 2 * overscan_y; - graphic_device->plnSizeX = mode->xres * graphic_device->gdfBytesPP; - - return graphic_device; -} - -/* - * Simplefb support. - */ -#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_VIDEO_DT_SIMPLEFB) -int sunxi_simplefb_setup(void *blob) -{ - static GraphicDevice *graphic_device = &sunxi_display.graphic_device; - int offset, ret; - u64 start, size; - const char *pipeline = NULL; - -#ifdef CONFIG_MACH_SUN4I -#define PIPELINE_PREFIX "de_fe0-" -#else -#define PIPELINE_PREFIX -#endif - - switch (sunxi_display.monitor) { - case sunxi_monitor_none: - return 0; - case sunxi_monitor_dvi: - case sunxi_monitor_hdmi: - pipeline = PIPELINE_PREFIX "de_be0-lcd0-hdmi"; - break; - case sunxi_monitor_lcd: - pipeline = PIPELINE_PREFIX "de_be0-lcd0"; - break; - case sunxi_monitor_vga: -#ifdef CONFIG_VIDEO_VGA - pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0"; -#elif defined CONFIG_VIDEO_VGA_VIA_LCD - pipeline = PIPELINE_PREFIX "de_be0-lcd0"; -#endif - break; - case sunxi_monitor_composite_pal: - case sunxi_monitor_composite_ntsc: - case sunxi_monitor_composite_pal_m: - case sunxi_monitor_composite_pal_nc: - pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0"; - break; - } - - /* Find a prefilled simpefb node, matching out pipeline config */ - offset = fdt_node_offset_by_compatible(blob, -1, - "allwinner,simple-framebuffer"); - while (offset >= 0) { - ret = fdt_stringlist_search(blob, offset, "allwinner,pipeline", - pipeline); - if (ret == 0) - break; - offset = fdt_node_offset_by_compatible(blob, offset, - "allwinner,simple-framebuffer"); - } - if (offset < 0) { - eprintf("Cannot setup simplefb: node not found\n"); - return 0; /* Keep older kernels working */ - } - - /* - * Do not report the framebuffer as free RAM to the OS, note we cannot - * use fdt_add_mem_rsv() here, because then it is still seen as RAM, - * and e.g. Linux refuses to iomap RAM on ARM, see: - * linux/arch/arm/mm/ioremap.c around line 301. - */ - start = gd->bd->bi_dram[0].start; - size = gd->bd->bi_dram[0].size - sunxi_display.fb_size; - ret = fdt_fixup_memory_banks(blob, &start, &size, 1); - if (ret) { - eprintf("Cannot setup simplefb: Error reserving memory\n"); - return ret; - } - - ret = fdt_setup_simplefb_node(blob, offset, sunxi_display.fb_addr, - graphic_device->winSizeX, graphic_device->winSizeY, - graphic_device->plnSizeX, "x8r8g8b8"); - if (ret) - eprintf("Cannot setup simplefb: Error setting properties\n"); - - return ret; -} -#endif /* CONFIG_OF_BOARD_SETUP && CONFIG_VIDEO_DT_SIMPLEFB */ -- cgit v1.3.1 From 30ca20234e0cdce6e514ee6c1e73c97578efaea3 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Mon, 27 Mar 2017 19:22:30 +0200 Subject: sunxi: video: Convert lcdc to use struct display_timing Video driver for older Allwinner SoCs uses cfb console framework which in turn uses struct ctfb_res_modes to hold timing informations. However, DM video framework uses different structure - struct display_timing. It makes more sense to convert lcdc to use new timing structure because all new drivers should use DM video framework and older drivers might be rewritten to use new framework too. Signed-off-by: Jernej Skrabec Acked-by: Maxime Ripard Signed-off-by: Maxime Ripard --- arch/arm/include/asm/arch-sunxi/lcdc.h | 6 ++-- drivers/video/sunxi/lcdc.c | 64 ++++++++++++++++------------------ drivers/video/sunxi/sunxi_display.c | 35 +++++++++++++++++-- 3 files changed, 67 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-sunxi/lcdc.h b/arch/arm/include/asm/arch-sunxi/lcdc.h index e4c8c160ed1..a751698b4fe 100644 --- a/arch/arm/include/asm/arch-sunxi/lcdc.h +++ b/arch/arm/include/asm/arch-sunxi/lcdc.h @@ -10,7 +10,7 @@ #ifndef _LCDC_H #define _LCDC_H -struct ctfb_res_modes; +#include struct sunxi_lcdc_reg { u32 ctrl; /* 0x00 */ @@ -118,11 +118,11 @@ struct sunxi_lcdc_reg { void lcdc_init(struct sunxi_lcdc_reg * const lcdc); void lcdc_enable(struct sunxi_lcdc_reg * const lcdc, int depth); void lcdc_tcon0_mode_set(struct sunxi_lcdc_reg * const lcdc, - const struct ctfb_res_modes *mode, + const struct display_timing *mode, int clk_div, bool for_ext_vga_dac, int depth, int dclk_phase); void lcdc_tcon1_mode_set(struct sunxi_lcdc_reg * const lcdc, - const struct ctfb_res_modes *mode, + const struct display_timing *mode, bool ext_hvsync, bool is_composite); #endif /* _LCDC_H */ diff --git a/drivers/video/sunxi/lcdc.c b/drivers/video/sunxi/lcdc.c index caf1859b0db..8c8fb2e4ee5 100644 --- a/drivers/video/sunxi/lcdc.c +++ b/drivers/video/sunxi/lcdc.c @@ -13,15 +13,13 @@ #include #include -#include "../videomodes.h" - -static int lcdc_get_clk_delay(const struct ctfb_res_modes *mode, int tcon) +static int lcdc_get_clk_delay(const struct display_timing *mode, int tcon) { int delay; - delay = mode->lower_margin + mode->vsync_len + - mode->upper_margin; - if (mode->vmode == FB_VMODE_INTERLACED) + delay = mode->vfront_porch.typ + mode->vsync_len.typ + + mode->vback_porch.typ; + if (mode->flags & DISPLAY_FLAGS_INTERLACED) delay /= 2; if (tcon == 1) delay -= 2; @@ -70,7 +68,7 @@ void lcdc_enable(struct sunxi_lcdc_reg * const lcdc, int depth) } void lcdc_tcon0_mode_set(struct sunxi_lcdc_reg * const lcdc, - const struct ctfb_res_modes *mode, + const struct display_timing *mode, int clk_div, bool for_ext_vga_dac, int depth, int dclk_phase) { @@ -87,22 +85,22 @@ void lcdc_tcon0_mode_set(struct sunxi_lcdc_reg * const lcdc, writel(SUNXI_LCDC_TCON0_DCLK_ENABLE | SUNXI_LCDC_TCON0_DCLK_DIV(clk_div), &lcdc->tcon0_dclk); - writel(SUNXI_LCDC_X(mode->xres) | - SUNXI_LCDC_Y(mode->yres), &lcdc->tcon0_timing_active); + writel(SUNXI_LCDC_X(mode->hactive.typ) | + SUNXI_LCDC_Y(mode->vactive.typ), &lcdc->tcon0_timing_active); - bp = mode->hsync_len + mode->left_margin; - total = mode->xres + mode->right_margin + bp; + bp = mode->hsync_len.typ + mode->hback_porch.typ; + total = mode->hactive.typ + mode->hfront_porch.typ + bp; writel(SUNXI_LCDC_TCON0_TIMING_H_TOTAL(total) | SUNXI_LCDC_TCON0_TIMING_H_BP(bp), &lcdc->tcon0_timing_h); - bp = mode->vsync_len + mode->upper_margin; - total = mode->yres + mode->lower_margin + bp; + bp = mode->vsync_len.typ + mode->vback_porch.typ; + total = mode->vactive.typ + mode->vfront_porch.typ + bp; writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) | SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v); #ifdef CONFIG_VIDEO_LCD_IF_PARALLEL - writel(SUNXI_LCDC_X(mode->hsync_len) | - SUNXI_LCDC_Y(mode->vsync_len), &lcdc->tcon0_timing_sync); + writel(SUNXI_LCDC_X(mode->hsync_len.typ) | + SUNXI_LCDC_Y(mode->vsync_len.typ), &lcdc->tcon0_timing_sync); writel(0, &lcdc->tcon0_hv_intf); writel(0, &lcdc->tcon0_cpu_intf); @@ -131,9 +129,9 @@ void lcdc_tcon0_mode_set(struct sunxi_lcdc_reg * const lcdc, } val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(dclk_phase); - if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT)) + if (mode->flags & DISPLAY_FLAGS_HSYNC_LOW) val |= SUNXI_LCDC_TCON_HSYNC_MASK; - if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) + if (mode->flags & DISPLAY_FLAGS_VSYNC_LOW) val |= SUNXI_LCDC_TCON_VSYNC_MASK; #ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH @@ -146,7 +144,7 @@ void lcdc_tcon0_mode_set(struct sunxi_lcdc_reg * const lcdc, } void lcdc_tcon1_mode_set(struct sunxi_lcdc_reg * const lcdc, - const struct ctfb_res_modes *mode, + const struct display_timing *mode, bool ext_hvsync, bool is_composite) { int bp, clk_delay, total, val, yres; @@ -157,40 +155,40 @@ void lcdc_tcon1_mode_set(struct sunxi_lcdc_reg * const lcdc, clk_delay = lcdc_get_clk_delay(mode, 1); writel(SUNXI_LCDC_TCON1_CTRL_ENABLE | - ((mode->vmode == FB_VMODE_INTERLACED) ? + ((mode->flags & DISPLAY_FLAGS_INTERLACED) ? SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE : 0) | SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon1_ctrl); - yres = mode->yres; - if (mode->vmode == FB_VMODE_INTERLACED) + yres = mode->vactive.typ; + if (mode->flags & DISPLAY_FLAGS_INTERLACED) yres /= 2; - writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), + writel(SUNXI_LCDC_X(mode->hactive.typ) | SUNXI_LCDC_Y(yres), &lcdc->tcon1_timing_source); - writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), + writel(SUNXI_LCDC_X(mode->hactive.typ) | SUNXI_LCDC_Y(yres), &lcdc->tcon1_timing_scale); - writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), + writel(SUNXI_LCDC_X(mode->hactive.typ) | SUNXI_LCDC_Y(yres), &lcdc->tcon1_timing_out); - bp = mode->hsync_len + mode->left_margin; - total = mode->xres + mode->right_margin + bp; + bp = mode->hsync_len.typ + mode->hback_porch.typ; + total = mode->hactive.typ + mode->hfront_porch.typ + bp; writel(SUNXI_LCDC_TCON1_TIMING_H_TOTAL(total) | SUNXI_LCDC_TCON1_TIMING_H_BP(bp), &lcdc->tcon1_timing_h); - bp = mode->vsync_len + mode->upper_margin; - total = mode->yres + mode->lower_margin + bp; - if (mode->vmode == FB_VMODE_NONINTERLACED) + bp = mode->vsync_len.typ + mode->vback_porch.typ; + total = mode->vactive.typ + mode->vfront_porch.typ + bp; + if (!(mode->flags & DISPLAY_FLAGS_INTERLACED)) total *= 2; writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(total) | SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc->tcon1_timing_v); - writel(SUNXI_LCDC_X(mode->hsync_len) | - SUNXI_LCDC_Y(mode->vsync_len), &lcdc->tcon1_timing_sync); + writel(SUNXI_LCDC_X(mode->hsync_len.typ) | + SUNXI_LCDC_Y(mode->vsync_len.typ), &lcdc->tcon1_timing_sync); if (ext_hvsync) { val = 0; - if (mode->sync & FB_SYNC_HOR_HIGH_ACT) + if (mode->flags & DISPLAY_FLAGS_HSYNC_HIGH) val |= SUNXI_LCDC_TCON_HSYNC_MASK; - if (mode->sync & FB_SYNC_VERT_HIGH_ACT) + if (mode->flags & DISPLAY_FLAGS_VSYNC_HIGH) val |= SUNXI_LCDC_TCON_VSYNC_MASK; writel(val, &lcdc->tcon1_io_polarity); diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c index 48192ef87ea..92c9d06054f 100644 --- a/drivers/video/sunxi/sunxi_display.c +++ b/drivers/video/sunxi/sunxi_display.c @@ -721,12 +721,40 @@ static void sunxi_lcdc_backlight_enable(void) gpio_direction_output(pin, PWM_ON); } +static void sunxi_ctfb_mode_to_display_timing(const struct ctfb_res_modes *mode, + struct display_timing *timing) +{ + timing->pixelclock.typ = mode->pixclock_khz * 1000; + + timing->hactive.typ = mode->xres; + timing->hfront_porch.typ = mode->right_margin; + timing->hback_porch.typ = mode->left_margin; + timing->hsync_len.typ = mode->hsync_len; + + timing->vactive.typ = mode->yres; + timing->vfront_porch.typ = mode->lower_margin; + timing->vback_porch.typ = mode->upper_margin; + timing->vsync_len.typ = mode->vsync_len; + + if (mode->sync & FB_SYNC_HOR_HIGH_ACT) + timing->flags |= DISPLAY_FLAGS_HSYNC_HIGH; + else + timing->flags |= DISPLAY_FLAGS_HSYNC_LOW; + if (mode->sync & FB_SYNC_VERT_HIGH_ACT) + timing->flags |= DISPLAY_FLAGS_VSYNC_HIGH; + else + timing->flags |= DISPLAY_FLAGS_VSYNC_LOW; + if (mode->vmode == FB_VMODE_INTERLACED) + timing->flags |= DISPLAY_FLAGS_INTERLACED; +} + static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode, bool for_ext_vga_dac) { struct sunxi_lcdc_reg * const lcdc = (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; int clk_div, clk_double, pin; + struct display_timing timing; #if defined CONFIG_MACH_SUN8I && defined CONFIG_VIDEO_LCD_IF_LVDS for (pin = SUNXI_GPD(18); pin <= SUNXI_GPD(27); pin++) { @@ -746,7 +774,8 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode, sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double); - lcdc_tcon0_mode_set(lcdc, mode, clk_div, for_ext_vga_dac, + sunxi_ctfb_mode_to_display_timing(mode, &timing); + lcdc_tcon0_mode_set(lcdc, &timing, clk_div, for_ext_vga_dac, sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE); } @@ -757,8 +786,10 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode, { struct sunxi_lcdc_reg * const lcdc = (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; + struct display_timing timing; - lcdc_tcon1_mode_set(lcdc, mode, use_portd_hvsync, + sunxi_ctfb_mode_to_display_timing(mode, &timing); + lcdc_tcon1_mode_set(lcdc, &timing, use_portd_hvsync, sunxi_is_composite()); if (use_portd_hvsync) { -- cgit v1.3.1 From 1ae5def6be484b0ee2c6ef72c750349b72342ac9 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Mon, 27 Mar 2017 19:22:31 +0200 Subject: sunxi: Add clock support for DE2/HDMI/TCON on newer SoCs This is needed for HDMI, which will be added later. Signed-off-by: Jernej Skrabec Reviewed-by: Simon Glass Signed-off-by: Maxime Ripard --- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 54 +++++++++++++++++++++++++++ arch/arm/mach-sunxi/clock_sun6i.c | 40 +++++++++++++++++++- board/sunxi/Kconfig | 6 +++ drivers/video/sunxi/lcdc.c | 4 ++ 4 files changed, 103 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 1aefd5a64c1..a44ea775763 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -67,13 +67,22 @@ struct sunxi_ccm_reg { u32 dram_pll_cfg; /* 0xf8 PLL_DDR cfg register, A33 only */ u32 mbus_reset; /* 0xfc MBUS reset control, A33 only */ u32 dram_clk_gate; /* 0x100 DRAM module gating */ +#ifdef CONFIG_SUNXI_DE2 + u32 de_clk_cfg; /* 0x104 DE module clock */ +#else u32 be0_clk_cfg; /* 0x104 BE0 module clock */ +#endif u32 be1_clk_cfg; /* 0x108 BE1 module clock */ u32 fe0_clk_cfg; /* 0x10c FE0 module clock */ u32 fe1_clk_cfg; /* 0x110 FE1 module clock */ u32 mp_clk_cfg; /* 0x114 MP module clock */ +#ifdef CONFIG_SUNXI_DE2 + u32 lcd0_clk_cfg; /* 0x118 LCD0 module clock */ + u32 lcd1_clk_cfg; /* 0x11c LCD1 module clock */ +#else u32 lcd0_ch0_clk_cfg; /* 0x118 LCD0 CH0 module clock */ u32 lcd1_ch0_clk_cfg; /* 0x11c LCD1 CH0 module clock */ +#endif u32 reserved14[3]; u32 lcd0_ch1_clk_cfg; /* 0x12c LCD0 CH1 module clock */ u32 lcd1_ch1_clk_cfg; /* 0x130 LCD1 CH1 module clock */ @@ -85,7 +94,11 @@ struct sunxi_ccm_reg { u32 dmic_clk_cfg; /* 0x148 Digital Mic module clock*/ u32 reserved15; u32 hdmi_clk_cfg; /* 0x150 HDMI module clock */ +#ifdef CONFIG_SUNXI_DE2 + u32 hdmi_slow_clk_cfg; /* 0x154 HDMI slow module clock */ +#else u32 ps_clk_cfg; /* 0x154 PS module clock */ +#endif u32 mtc_clk_cfg; /* 0x158 MTC module clock */ u32 mbus0_clk_cfg; /* 0x15c MBUS0 module clock */ u32 mbus1_clk_cfg; /* 0x160 MBUS1 module clock */ @@ -193,6 +206,7 @@ struct sunxi_ccm_reg { #define CCM_PLL3_CTRL_N_MASK (0x7f << CCM_PLL3_CTRL_N_SHIFT) #define CCM_PLL3_CTRL_N(n) ((((n) - 1) & 0x7f) << 8) #define CCM_PLL3_CTRL_INTEGER_MODE (0x1 << 24) +#define CCM_PLL3_CTRL_LOCK (0x1 << 28) #define CCM_PLL3_CTRL_EN (0x1 << 31) #define CCM_PLL5_CTRL_M(n) ((((n) - 1) & 0x3) << 0) @@ -222,6 +236,16 @@ struct sunxi_ccm_reg { #define CCM_MIPI_PLL_CTRL_LDO_EN (0x3 << 22) #define CCM_MIPI_PLL_CTRL_EN (0x1 << 31) +#define CCM_PLL10_CTRL_M_SHIFT 0 +#define CCM_PLL10_CTRL_M_MASK (0xf << CCM_PLL10_CTRL_M_SHIFT) +#define CCM_PLL10_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_PLL10_CTRL_N_SHIFT 8 +#define CCM_PLL10_CTRL_N_MASK (0x7f << CCM_PLL10_CTRL_N_SHIFT) +#define CCM_PLL10_CTRL_N(n) ((((n) - 1) & 0x7f) << 8) +#define CCM_PLL10_CTRL_INTEGER_MODE (0x1 << 24) +#define CCM_PLL10_CTRL_LOCK (0x1 << 28) +#define CCM_PLL10_CTRL_EN (0x1 << 31) + #define CCM_PLL11_CTRL_N(n) ((((n) - 1) & 0x3f) << 8) #define CCM_PLL11_CTRL_SIGMA_DELTA_EN (0x1 << 24) #define CCM_PLL11_CTRL_UPD (0x1 << 30) @@ -273,9 +297,15 @@ struct sunxi_ccm_reg { #define AHB_GATE_OFFSET_DRC0 25 #define AHB_GATE_OFFSET_DE_FE0 14 #define AHB_GATE_OFFSET_DE_BE0 12 +#define AHB_GATE_OFFSET_DE 12 #define AHB_GATE_OFFSET_HDMI 11 +#ifndef CONFIG_SUNXI_DE2 #define AHB_GATE_OFFSET_LCD1 5 #define AHB_GATE_OFFSET_LCD0 4 +#else +#define AHB_GATE_OFFSET_LCD1 4 +#define AHB_GATE_OFFSET_LCD0 3 +#endif #define CCM_MMC_CTRL_M(x) ((x) - 1) #define CCM_MMC_CTRL_OCLK_DLY(x) ((x) << 8) @@ -357,6 +387,12 @@ struct sunxi_ccm_reg { #define CCM_LCD_CH1_CTRL_PLL7_2X (3 << 24) #define CCM_LCD_CH1_CTRL_GATE (0x1 << 31) +#define CCM_LCD0_CTRL_GATE (0x1 << 31) +#define CCM_LCD0_CTRL_M(n) ((((n) - 1) & 0xf) << 0) + +#define CCM_LCD1_CTRL_GATE (0x1 << 31) +#define CCM_LCD1_CTRL_M(n) ((((n) - 1) & 0xf) << 0) + #define CCM_HDMI_CTRL_M(n) ((((n) - 1) & 0xf) << 0) #define CCM_HDMI_CTRL_PLL_MASK (3 << 24) #define CCM_HDMI_CTRL_PLL3 (0 << 24) @@ -366,6 +402,8 @@ struct sunxi_ccm_reg { #define CCM_HDMI_CTRL_DDC_GATE (0x1 << 30) #define CCM_HDMI_CTRL_GATE (0x1 << 31) +#define CCM_HDMI_SLOW_CTRL_DDC_GATE (1 << 31) + #if defined(CONFIG_MACH_SUN50I) #define MBUS_CLK_DEFAULT 0x81000002 /* PLL6x2 / 3 */ #elif defined(CONFIG_MACH_SUN8I) @@ -393,9 +431,16 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_DRC0 25 #define AHB_RESET_OFFSET_DE_FE0 14 #define AHB_RESET_OFFSET_DE_BE0 12 +#define AHB_RESET_OFFSET_DE 12 #define AHB_RESET_OFFSET_HDMI 11 +#define AHB_RESET_OFFSET_HDMI2 10 +#ifndef CONFIG_SUNXI_DE2 #define AHB_RESET_OFFSET_LCD1 5 #define AHB_RESET_OFFSET_LCD0 4 +#else +#define AHB_RESET_OFFSET_LCD1 4 +#define AHB_RESET_OFFSET_LCD0 3 +#endif /* ahb_reset2 offsets */ #define AHB_RESET_OFFSET_EPHY 2 @@ -418,6 +463,13 @@ struct sunxi_ccm_reg { #define CCM_DE_CTRL_PLL10 (5 << 24) #define CCM_DE_CTRL_GATE (1 << 31) +/* CCM bits common to all Display Engine 2.0 clock ctrl regs */ +#define CCM_DE2_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_DE2_CTRL_PLL_MASK (3 << 24) +#define CCM_DE2_CTRL_PLL6_2X (0 << 24) +#define CCM_DE2_CTRL_PLL10 (1 << 24) +#define CCM_DE2_CTRL_GATE (0x1 << 31) + /* CCU security switch, H3 only */ #define CCM_SEC_SWITCH_MBUS_NONSEC (1 << 2) #define CCM_SEC_SWITCH_BUS_NONSEC (1 << 1) @@ -426,7 +478,9 @@ struct sunxi_ccm_reg { #ifndef __ASSEMBLY__ void clock_set_pll1(unsigned int hz); void clock_set_pll3(unsigned int hz); +void clock_set_pll3_factors(int m, int n); void clock_set_pll5(unsigned int clk, bool sigma_delta_enable); +void clock_set_pll10(unsigned int hz); void clock_set_pll11(unsigned int clk, bool sigma_delta_enable); void clock_set_mipi_pll(unsigned int hz); unsigned int clock_get_pll3(void); diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c index 9068c88ab2f..631bc6e2500 100644 --- a/arch/arm/mach-sunxi/clock_sun6i.c +++ b/arch/arm/mach-sunxi/clock_sun6i.c @@ -35,7 +35,7 @@ void clock_init_safe(void) clrbits_le32(&prcm->pll_ctrl1, PRCM_PLL_CTRL_LDO_KEY_MASK); #endif -#ifdef CONFIG_MACH_SUN8I_R40 +#if defined(CONFIG_MACH_SUN8I_R40) || defined(CONFIG_MACH_SUN50I) /* Set PLL lock enable bits and switch to old lock mode */ writel(GENMASK(12, 0), &ccm->pll_lock_ctrl); #endif @@ -150,6 +150,22 @@ void clock_set_pll3(unsigned int clk) &ccm->pll3_cfg); } +#ifdef CONFIG_SUNXI_DE2 +void clock_set_pll3_factors(int m, int n) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* PLL3 rate = 24000000 * n / m */ + writel(CCM_PLL3_CTRL_EN | CCM_PLL3_CTRL_INTEGER_MODE | + CCM_PLL3_CTRL_N(n) | CCM_PLL3_CTRL_M(m), + &ccm->pll3_cfg); + + while (!(readl(&ccm->pll3_cfg) & CCM_PLL3_CTRL_LOCK)) + ; +} +#endif + void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) { struct sunxi_ccm_reg * const ccm = @@ -222,6 +238,28 @@ done: } #endif +#ifdef CONFIG_SUNXI_DE2 +void clock_set_pll10(unsigned int clk) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + const int m = 2; /* 12 MHz steps */ + + if (clk == 0) { + clrbits_le32(&ccm->pll10_cfg, CCM_PLL10_CTRL_EN); + return; + } + + /* PLL10 rate = 24000000 * n / m */ + writel(CCM_PLL10_CTRL_EN | CCM_PLL10_CTRL_INTEGER_MODE | + CCM_PLL10_CTRL_N(clk / (24000000 / m)) | CCM_PLL10_CTRL_M(m), + &ccm->pll10_cfg); + + while (!(readl(&ccm->pll10_cfg) & CCM_PLL10_CTRL_LOCK)) + ; +} +#endif + #if defined(CONFIG_MACH_SUN8I_A33) || \ defined(CONFIG_MACH_SUN8I_R40) || \ defined(CONFIG_MACH_SUN50I) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index c4fba849213..7350e25e289 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -58,6 +58,7 @@ config SUNXI_GEN_SUN6I config MACH_SUNXI_H3_H5 bool + select SUNXI_DE2 select SUNXI_GEN_SUN6I select SUPPORT_SPL @@ -153,6 +154,7 @@ config MACH_SUN9I config MACH_SUN50I bool "sun50i (Allwinner A64)" select ARM64 + select SUNXI_DE2 select SUNXI_GEN_SUN6I select SUNXI_HIGH_SRAM select SUPPORT_SPL @@ -689,6 +691,10 @@ config VIDEO_LCD_IF_PARALLEL config VIDEO_LCD_IF_LVDS bool +config SUNXI_DE2 + bool + default n + choice prompt "LCD panel support" diff --git a/drivers/video/sunxi/lcdc.c b/drivers/video/sunxi/lcdc.c index 8c8fb2e4ee5..7d215b713ef 100644 --- a/drivers/video/sunxi/lcdc.c +++ b/drivers/video/sunxi/lcdc.c @@ -74,9 +74,11 @@ void lcdc_tcon0_mode_set(struct sunxi_lcdc_reg * const lcdc, { int bp, clk_delay, total, val; +#ifndef CONFIG_SUNXI_DE2 /* Use tcon0 */ clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK, SUNXI_LCDC_CTRL_IO_MAP_TCON0); +#endif clk_delay = lcdc_get_clk_delay(mode, 0); writel(SUNXI_LCDC_TCON0_CTRL_ENABLE | @@ -149,9 +151,11 @@ void lcdc_tcon1_mode_set(struct sunxi_lcdc_reg * const lcdc, { int bp, clk_delay, total, val, yres; +#ifndef CONFIG_SUNXI_DE2 /* Use tcon1 */ clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK, SUNXI_LCDC_CTRL_IO_MAP_TCON1); +#endif clk_delay = lcdc_get_clk_delay(mode, 1); writel(SUNXI_LCDC_TCON1_CTRL_ENABLE | -- cgit v1.3.1 From e8f86a026125ff2b2d6bd6eac73d2542852aab84 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Tue, 25 Apr 2017 01:39:51 +0800 Subject: sunxi: fix the default value of CONS_INDEX on non-A23/A33 SUN8I Only A23/A33 in SUN8I want a default value of CONS_INDEX of 5, for other chips the default value is 1 like other Allwinner SoCs. Fix this default value. The original wrong value has lead to wrong console on H3 Orange Pi boards. Fixes: 7095f8641863 ("sunxi: Convert CONS_INDEX to Kconfig") Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard --- drivers/serial/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index a753367ee14..58320666b7d 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -48,11 +48,11 @@ config CONS_INDEX int "UART used for console" depends on ARCH_SUNXI default 2 if MACH_SUN5I - default 5 if MACH_SUN8I + default 5 if MACH_SUN8I_A23 || MACH_SUN8I_A33 default 1 help Configures the console index. - For Allwinner SoC., default values are 2 for SUN5I and 5 for SUN8I. + For Allwinner SoC., default values are 2 for SUN5I and 5 for A23/A33. Otherwise, the index equals 1. config DM_SERIAL -- cgit v1.3.1 From 2511b2ed4df36467898952aa7825abbe8d0a211f Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 15 Apr 2017 13:46:22 +0200 Subject: musb: properly detect failed initialization of controller We want to check the result of musb_init_controller and not the address were the result is stored. Signed-off-by: Heinrich Schuchardt --- drivers/usb/musb-new/musb_uboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index ea71f759476..8662c0ff707 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -446,7 +446,7 @@ int musb_register(struct musb_hdrc_platform_data *plat, void *bdata, } *musbp = musb_init_controller(plat, (struct device *)bdata, ctl_regs); - if (!musbp) { + if (!*musbp) { printf("Failed to init the controller\n"); return -EIO; } -- cgit v1.3.1 From 7f2e59aee5894ffc1d79b485f45ae00902baa738 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 15 Apr 2017 14:29:54 +0200 Subject: usb: musb: avoid out of bound access in udc_setup_ep For id = 15 an out of bound access occurs in udc_setup_ep(). Increase the size of epinfo[] from 30 to 32 to encompass ids 0..15. The problem was highlighted by cppcheck. Signed-off-by: Heinrich Schuchardt --- drivers/usb/musb/musb_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c index 87640f4e326..d643334a2e8 100644 --- a/drivers/usb/musb/musb_udc.c +++ b/drivers/usb/musb/musb_udc.c @@ -85,7 +85,7 @@ do { \ /* static implies these initialized to 0 or NULL */ static int debug_setup; static int debug_level; -static struct musb_epinfo epinfo[MAX_ENDPOINT * 2]; +static struct musb_epinfo epinfo[MAX_ENDPOINT * 2 + 2]; static enum ep0_state_enum { IDLE = 0, TX, @@ -944,7 +944,7 @@ int udc_init(void) musbr = musb_cfg.regs; /* Initialize the endpoints */ - for (ep_loop = 0; ep_loop < MAX_ENDPOINT * 2; ep_loop++) { + for (ep_loop = 0; ep_loop <= MAX_ENDPOINT * 2; ep_loop++) { epinfo[ep_loop].epnum = (ep_loop / 2) + 1; epinfo[ep_loop].epdir = ep_loop % 2; /* OUT, IN */ epinfo[ep_loop].epsize = 0; -- cgit v1.3.1 From 83cb46c286beb5406aaed2e0d5895719717804b3 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Mon, 17 Apr 2017 19:13:17 +0300 Subject: ehci-ppc4xx: Prepare for usage of readl()/writel() accessors We used to have opencoded ehci_readl()/writel() which required no external functions to be called. Now with attempt to switch to generic readl()/writel() accessors we see a missing declaration of those accessors in ehci-ppc4xx. Something like that happens if applied http://patchwork.ozlabs.org/patch/726714/: ---------------->8--------------- CC drivers/usb/host/ehci-ppc4xx.o drivers/usb/host/ehci-ppc4xx.c: In function 'ehci_hcd_init': drivers/usb/host/ehci-ppc4xx.c:23:3: warning: implicit declaration of function 'readl' [-Wimplicit-function-declaration] HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); ^ ---------------->8--------------- Signed-off-by: Alexey Brodkin Cc: Tom Rini Cc: Marek Vasut Cc: Stefan Roese Reviewed-by: Stefan Roese --- drivers/usb/host/ehci-ppc4xx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-ppc4xx.c b/drivers/usb/host/ehci-ppc4xx.c index 9aee3ff786c..9d235776428 100644 --- a/drivers/usb/host/ehci-ppc4xx.c +++ b/drivers/usb/host/ehci-ppc4xx.c @@ -8,6 +8,7 @@ */ #include #include +#include #include "ehci.h" -- cgit v1.3.1 From 43b41566f72c3ff1074fe686f37227ebe33e11f9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 16 Apr 2017 21:01:11 -0600 Subject: dm: sandbox: pwm: Add a basic pwm test Unfortunately a test for the PWM uclass was not included when it was submitted. This was noticed when trying to add more functionality: http://patchwork.ozlabs.org/patch/748172/ Add a simple test to get us started. Signed-off-by: Simon Glass --- arch/sandbox/dts/test.dts | 8 +++++ configs/sandbox_defconfig | 2 ++ configs/sandbox_noblk_defconfig | 2 ++ configs/sandbox_spl_defconfig | 2 ++ drivers/pwm/Kconfig | 8 +++++ drivers/pwm/Makefile | 1 + drivers/pwm/sandbox_pwm.c | 75 +++++++++++++++++++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/pwm.c | 32 ++++++++++++++++++ 9 files changed, 131 insertions(+) create mode 100644 drivers/pwm/sandbox_pwm.c create mode 100644 test/dm/pwm.c (limited to 'drivers') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index fff175d1b7a..50bcdebf74d 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -272,6 +272,14 @@ power-domains = <&pwrdom 2>; }; + pwm { + compatible = "sandbox,pwm"; + }; + + pwm2 { + compatible = "sandbox,pwm"; + }; + ram { compatible = "sandbox,ram"; }; diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 9814ea3b819..cdaf3bb7433 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -173,3 +173,5 @@ CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y CONFIG_UT_ENV=y +CONFIG_DM_PWM=y +CONFIG_PWM_SANDBOX=y diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig index bba744332c2..087c7a84fc4 100644 --- a/configs/sandbox_noblk_defconfig +++ b/configs/sandbox_noblk_defconfig @@ -175,3 +175,5 @@ CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y CONFIG_UT_ENV=y +CONFIG_DM_PWM=y +CONFIG_PWM_SANDBOX=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 6fe21254fd8..ffdd15b6b58 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -179,3 +179,5 @@ CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y CONFIG_UT_ENV=y +CONFIG_DM_PWM=y +CONFIG_PWM_SANDBOX=y diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 37ea2b88eae..e8275580524 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -27,6 +27,14 @@ config PWM_ROCKCHIP Various options provided in the hardware (such as capture mode and continuous/single-shot) are not supported by the driver. +config PWM_SANDBOX + bool "Enable support for the sandbox PWM" + help + This is a sandbox PWM used for testing. It provides 3 channels and + records the settings passed into it, but otherwise does nothing + useful. The PWM can be enabled but is not connected to any outputs + so this is not very useful. + config PWM_TEGRA bool "Enable support for the Tegra PWM" depends on DM_PWM diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index b0371303851..29d59916cb9 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -15,4 +15,5 @@ obj-$(CONFIG_DM_PWM) += pwm-uclass.o obj-$(CONFIG_PWM_EXYNOS) += exynos_pwm.o obj-$(CONFIG_PWM_IMX) += pwm-imx.o pwm-imx-util.o obj-$(CONFIG_PWM_ROCKCHIP) += rk_pwm.o +obj-$(CONFIG_PWM_SANDBOX) += sandbox_pwm.o obj-$(CONFIG_PWM_TEGRA) += tegra_pwm.o diff --git a/drivers/pwm/sandbox_pwm.c b/drivers/pwm/sandbox_pwm.c new file mode 100644 index 00000000000..c2ce974ddea --- /dev/null +++ b/drivers/pwm/sandbox_pwm.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +enum { + NUM_CHANNELS = 3, +}; + +struct sandbox_pwm_chan { + uint period_ns; + uint duty_ns; + bool enable; +}; + +struct sandbox_pwm_priv { + struct sandbox_pwm_chan chan[NUM_CHANNELS]; +}; + +static int sandbox_pwm_set_config(struct udevice *dev, uint channel, + uint period_ns, uint duty_ns) +{ + struct sandbox_pwm_priv *priv = dev_get_priv(dev); + struct sandbox_pwm_chan *chan; + + if (channel >= NUM_CHANNELS) + return -ENOSPC; + chan = &priv->chan[channel]; + chan->period_ns = period_ns; + chan->duty_ns = duty_ns; + + return 0; +} + +static int sandbox_pwm_set_enable(struct udevice *dev, uint channel, + bool enable) +{ + struct sandbox_pwm_priv *priv = dev_get_priv(dev); + struct sandbox_pwm_chan *chan; + + if (channel >= NUM_CHANNELS) + return -ENOSPC; + chan = &priv->chan[channel]; + chan->enable = enable; + + return 0; +} + +static const struct pwm_ops sandbox_pwm_ops = { + .set_config = sandbox_pwm_set_config, + .set_enable = sandbox_pwm_set_enable, +}; + +static const struct udevice_id sandbox_pwm_ids[] = { + { .compatible = "sandbox,pwm" }, + { } +}; + +U_BOOT_DRIVER(warm_pwm_sandbox) = { + .name = "pwm_sandbox", + .id = UCLASS_PWM, + .of_match = sandbox_pwm_ids, + .ops = &sandbox_pwm_ops, + .priv_auto_alloc_size = sizeof(struct sandbox_pwm_priv), +}; diff --git a/test/dm/Makefile b/test/dm/Makefile index 1885e17c38d..e956915bc3d 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_DM_MAILBOX) += mailbox.o obj-$(CONFIG_DM_MMC) += mmc.o obj-$(CONFIG_DM_PCI) += pci.o obj-$(CONFIG_POWER_DOMAIN) += power-domain.o +obj-$(CONFIG_DM_PWM) += pwm.o obj-$(CONFIG_RAM) += ram.o obj-y += regmap.o obj-$(CONFIG_REMOTEPROC) += remoteproc.o diff --git a/test/dm/pwm.c b/test/dm/pwm.c new file mode 100644 index 00000000000..7bdc75af099 --- /dev/null +++ b/test/dm/pwm.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* Basic test of the pwm uclass */ +static int dm_test_pwm_base(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(uclass_get_device(UCLASS_PWM, 0, &dev)); + ut_assertok(pwm_set_config(dev, 0, 100, 50)); + ut_assertok(pwm_set_enable(dev, 0, true)); + ut_assertok(pwm_set_enable(dev, 1, true)); + ut_assertok(pwm_set_enable(dev, 2, true)); + ut_asserteq(-ENOSPC, pwm_set_enable(dev, 3, true)); + + ut_assertok(uclass_get_device(UCLASS_PWM, 1, &dev)); + ut_asserteq(-ENODEV, uclass_get_device(UCLASS_PWM, 2, &dev)); + + return 0; +} +DM_TEST(dm_test_pwm_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit v1.3.1 From 51c7f34809dab20e16316a5c4556fbb88c6905a8 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Wed, 19 Apr 2017 16:46:37 +0200 Subject: pinctrl: Kconfig: sort pinctrl config options to prevent future clutter This originally started out as "pinctrl: Kconfig: reorder to keep Rockchip options together" and tried to keep the Rockchip-related config options together. However, we now rewrite all chip-specific driver selections to start with CONFIG_PINCTRL_ (with the inadvertent changes to related Makefiles) and sort those alphabetically. And as this already means touching most of the file, we also reformat the help text to not exceed 80 characters (but make full use of those 80 characters). Signed-off-by: Philipp Tomsich Acked-by: Simon Glass --- configs/ap121_defconfig | 2 +- configs/chromebit_mickey_defconfig | 2 +- configs/chromebook_jerry_defconfig | 2 +- configs/chromebook_minnie_defconfig | 2 +- configs/evb-rk3036_defconfig | 2 +- configs/evb-rk3288_defconfig | 2 +- configs/evb-rk3328_defconfig | 2 +- configs/evb-rk3399_defconfig | 2 +- configs/fennec-rk3288_defconfig | 2 +- configs/firefly-rk3288_defconfig | 2 +- configs/kylin-rk3036_defconfig | 2 +- configs/miqi-rk3288_defconfig | 2 +- configs/popmetal-rk3288_defconfig | 2 +- configs/puma-rk3399_defconfig | 2 +- configs/rock2_defconfig | 2 +- configs/rock_defconfig | 2 +- configs/sandbox_defconfig | 4 +- configs/sandbox_noblk_defconfig | 4 +- configs/tinker-rk3288_defconfig | 2 +- drivers/pinctrl/Kconfig | 164 +++++++++++++++++++----------------- drivers/pinctrl/Makefile | 2 +- drivers/pinctrl/ath79/Makefile | 4 +- drivers/pinctrl/rockchip/Makefile | 10 +-- 23 files changed, 117 insertions(+), 105 deletions(-) (limited to 'drivers') diff --git a/configs/ap121_defconfig b/configs/ap121_defconfig index f3472ae16f5..2550aeecb73 100644 --- a/configs/ap121_defconfig +++ b/configs/ap121_defconfig @@ -40,7 +40,7 @@ CONFIG_DM_ETH=y CONFIG_AG7XXX=y CONFIG_PINCTRL=y CONFIG_PINCONF=y -CONFIG_AR933X_PINCTRL=y +CONFIG_PINCTRL_AR933X=y CONFIG_DM_SERIAL=y CONFIG_DEBUG_UART=y CONFIG_DEBUG_UART_AR933X=y diff --git a/configs/chromebit_mickey_defconfig b/configs/chromebit_mickey_defconfig index a29e4e5cf17..e1f96dce12d 100644 --- a/configs/chromebit_mickey_defconfig +++ b/configs/chromebit_mickey_defconfig @@ -51,7 +51,7 @@ CONFIG_MMC_DW_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y # CONFIG_SPL_PINCTRL_FULL is not set -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set CONFIG_PMIC_RK808=y diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig index e642b8dba16..baebca970bb 100644 --- a/configs/chromebook_jerry_defconfig +++ b/configs/chromebook_jerry_defconfig @@ -52,7 +52,7 @@ CONFIG_MMC_DW_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y # CONFIG_SPL_PINCTRL_FULL is not set -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set CONFIG_PMIC_RK808=y diff --git a/configs/chromebook_minnie_defconfig b/configs/chromebook_minnie_defconfig index 18123626798..ea57810e956 100644 --- a/configs/chromebook_minnie_defconfig +++ b/configs/chromebook_minnie_defconfig @@ -52,7 +52,7 @@ CONFIG_MMC_DW_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y # CONFIG_SPL_PINCTRL_FULL is not set -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set CONFIG_PMIC_RK808=y diff --git a/configs/evb-rk3036_defconfig b/configs/evb-rk3036_defconfig index 19ecae5e53d..4a5664dfa48 100644 --- a/configs/evb-rk3036_defconfig +++ b/configs/evb-rk3036_defconfig @@ -28,7 +28,7 @@ CONFIG_LED=y CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_PINCTRL=y -CONFIG_ROCKCHIP_RK3036_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3036=y CONFIG_RAM=y # CONFIG_SPL_SERIAL_PRESENT is not set CONFIG_DEBUG_UART=y diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig index aad25339987..6507011cabd 100644 --- a/configs/evb-rk3288_defconfig +++ b/configs/evb-rk3288_defconfig @@ -48,7 +48,7 @@ CONFIG_GMAC_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y # CONFIG_SPL_PINCTRL_FULL is not set -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_DM_PMIC=y CONFIG_PMIC_ACT8846=y CONFIG_REGULATOR_ACT8846=y diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig index a9304fe039e..c834a4af286 100644 --- a/configs/evb-rk3328_defconfig +++ b/configs/evb-rk3328_defconfig @@ -22,7 +22,7 @@ CONFIG_ROCKCHIP_GPIO=y CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_PINCTRL=y -CONFIG_ROCKCHIP_RK3328_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3328=y CONFIG_REGULATOR_PWM=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_RAM=y diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig index cef8506d997..b115f045073 100644 --- a/configs/evb-rk3399_defconfig +++ b/configs/evb-rk3399_defconfig @@ -39,7 +39,7 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y -CONFIG_ROCKCHIP_RK3399_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3399=y CONFIG_REGULATOR_PWM=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_PWM_ROCKCHIP=y diff --git a/configs/fennec-rk3288_defconfig b/configs/fennec-rk3288_defconfig index d1b0ffc467a..a2d273c804a 100644 --- a/configs/fennec-rk3288_defconfig +++ b/configs/fennec-rk3288_defconfig @@ -48,7 +48,7 @@ CONFIG_GMAC_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y # CONFIG_SPL_PINCTRL_FULL is not set -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_DM_PMIC=y CONFIG_PMIC_RK808=y CONFIG_DM_REGULATOR_FIXED=y diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig index b0741d7bd91..69a54921777 100644 --- a/configs/firefly-rk3288_defconfig +++ b/configs/firefly-rk3288_defconfig @@ -49,7 +49,7 @@ CONFIG_GMAC_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y # CONFIG_SPL_PINCTRL_FULL is not set -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set CONFIG_PMIC_ACT8846=y diff --git a/configs/kylin-rk3036_defconfig b/configs/kylin-rk3036_defconfig index 2b127307c83..ba65bc94986 100644 --- a/configs/kylin-rk3036_defconfig +++ b/configs/kylin-rk3036_defconfig @@ -29,7 +29,7 @@ CONFIG_LED=y CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_PINCTRL=y -CONFIG_ROCKCHIP_RK3036_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3036=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_RAM=y CONFIG_SYSRESET=y diff --git a/configs/miqi-rk3288_defconfig b/configs/miqi-rk3288_defconfig index 203824b8938..2b9da554a95 100644 --- a/configs/miqi-rk3288_defconfig +++ b/configs/miqi-rk3288_defconfig @@ -47,7 +47,7 @@ CONFIG_GMAC_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y # CONFIG_SPL_PINCTRL_FULL is not set -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_DM_PMIC=y CONFIG_PMIC_ACT8846=y CONFIG_REGULATOR_ACT8846=y diff --git a/configs/popmetal-rk3288_defconfig b/configs/popmetal-rk3288_defconfig index dfc84b9a83d..80bc83b2c2d 100644 --- a/configs/popmetal-rk3288_defconfig +++ b/configs/popmetal-rk3288_defconfig @@ -48,7 +48,7 @@ CONFIG_GMAC_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y # CONFIG_SPL_PINCTRL_FULL is not set -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_DM_PMIC=y CONFIG_PMIC_RK808=y CONFIG_DM_REGULATOR_FIXED=y diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig index 500f22093e1..137f7fb1ed4 100644 --- a/configs/puma-rk3399_defconfig +++ b/configs/puma-rk3399_defconfig @@ -50,7 +50,7 @@ CONFIG_ETH_DESIGNWARE=y CONFIG_GMAC_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y -CONFIG_ROCKCHIP_RK3399_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3399=y CONFIG_REGULATOR_PWM=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_PWM_ROCKCHIP=y diff --git a/configs/rock2_defconfig b/configs/rock2_defconfig index e9a32a93c2f..ae432ad14db 100644 --- a/configs/rock2_defconfig +++ b/configs/rock2_defconfig @@ -46,7 +46,7 @@ CONFIG_GMAC_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y # CONFIG_SPL_PINCTRL_FULL is not set -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set CONFIG_PMIC_ACT8846=y diff --git a/configs/rock_defconfig b/configs/rock_defconfig index b61286e84b6..8e817948835 100644 --- a/configs/rock_defconfig +++ b/configs/rock_defconfig @@ -33,7 +33,7 @@ CONFIG_LED=y CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_PINCTRL=y -CONFIG_ROCKCHIP_RK3188_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3188=y CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set CONFIG_PMIC_ACT8846=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index cdaf3bb7433..77a07ac3e14 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -114,8 +114,8 @@ CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_SANDBOX=y CONFIG_PINCTRL=y CONFIG_PINCONF=y -CONFIG_ROCKCHIP_RK3036_PINCTRL=y -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3036=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_PINCTRL_SANDBOX=y CONFIG_POWER_DOMAIN=y CONFIG_SANDBOX_POWER_DOMAIN=y diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig index 087c7a84fc4..c4610e8efb1 100644 --- a/configs/sandbox_noblk_defconfig +++ b/configs/sandbox_noblk_defconfig @@ -120,8 +120,8 @@ CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_SANDBOX=y CONFIG_PINCTRL=y CONFIG_PINCONF=y -CONFIG_ROCKCHIP_RK3036_PINCTRL=y -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3036=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_PINCTRL_SANDBOX=y CONFIG_DM_PMIC=y CONFIG_PMIC_ACT8846=y diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig index cec39384b3c..cd9189f0aff 100644 --- a/configs/tinker-rk3288_defconfig +++ b/configs/tinker-rk3288_defconfig @@ -48,7 +48,7 @@ CONFIG_GMAC_ROCKCHIP=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y # CONFIG_SPL_PINCTRL_FULL is not set -CONFIG_ROCKCHIP_RK3288_PINCTRL=y +CONFIG_PINCTRL_ROCKCHIP_RK3288=y CONFIG_DM_PMIC=y CONFIG_PMIC_RK808=y CONFIG_DM_REGULATOR_FIXED=y diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 355aeae854d..9cea6f202cf 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -105,7 +105,7 @@ config SPL_PINCONF if PINCTRL || SPL_PINCTRL -config AR933X_PINCTRL +config PINCTRL_AR933X bool "QCA/Athores ar933x pin control driver" depends on DM && SOC_AR933X help @@ -114,98 +114,118 @@ config AR933X_PINCTRL both the GPIO definitions and pin control functions for each available multiplex function. -config QCA953X_PINCTRL +config PINCTRL_AT91 + bool "AT91 pinctrl driver" + depends on DM + help + This option is to enable the AT91 pinctrl driver for AT91 PIO + controller. + + AT91 PIO controller is a combined gpio-controller, pin-mux and + pin-config module. Each I/O pin may be dedicated as a general-purpose + I/O or be assigned to a function of an embedded peripheral. Each I/O + pin has a glitch filter providing rejection of glitches lower than + one-half of peripheral clock cycle and a debouncing filter providing + rejection of unwanted pulses from key or push button operations. You + can also control the multi-driver capability, pull-up and pull-down + feature on each I/O pin. + +config PINCTRL_AT91PIO4 + bool "AT91 PIO4 pinctrl driver" + depends on DM + help + This option is to enable the AT91 pinctrl driver for AT91 PIO4 + controller which is available on SAMA5D2 SoC. + +config PINCTRL_PIC32 + bool "Microchip PIC32 pin-control and pin-mux driver" + depends on DM && MACH_PIC32 + default y + help + Supports individual pin selection and configuration for each + remappable peripheral available on Microchip PIC32 + SoCs. This driver is controlled by a device tree node which + contains both GPIO defintion and pin control functions. + +config PINCTRL_QCA953X bool "QCA/Athores qca953x pin control driver" depends on DM && SOC_QCA953X help Support pin multiplexing control on QCA/Athores qca953x SoCs. - The driver is controlled by a device tree node which contains - both the GPIO definitions and pin control functions for each - available multiplex function. -config ROCKCHIP_RK3036_PINCTRL + The driver is controlled by a device tree node which contains both + the GPIO definitions and pin control functions for each available + multiplex function. + +config PINCTRL_ROCKCHIP_RK3036 bool "Rockchip rk3036 pin control driver" depends on DM help - Support pin multiplexing control on Rockchip rk3036 SoCs. The driver is - controlled by a device tree node which contains both the GPIO - definitions and pin control functions for each available multiplex - function. + Support pin multiplexing control on Rockchip rk3036 SoCs. + + The driver is controlled by a device tree node which contains both + the GPIO definitions and pin control functions for each available + multiplex function. -config ROCKCHIP_RK3188_PINCTRL +config PINCTRL_ROCKCHIP_RK3188 bool "Rockchip rk3188 pin control driver" depends on DM help - Support pin multiplexing control on Rockchip rk3188 SoCs. The driver - is controlled by a device tree node which contains both the GPIO - definitions and pin control functions for each available multiplex - function. + Support pin multiplexing control on Rockchip rk3188 SoCs. -config ROCKCHIP_RK3288_PINCTRL - bool "Rockchip rk3288 pin control driver" - depends on DM - help - Support pin multiplexing control on Rockchip rk3288 SoCs. The driver - is controlled by a device tree node which contains both the GPIO - definitions and pin control functions for each available multiplex - function. + The driver is controlled by a device tree node which contains both + the GPIO definitions and pin control functions for each available + multiplex function. -config PINCTRL_AT91 - bool "AT91 pinctrl driver" +config PINCTRL_ROCKCHIP_RK3288 + bool "Rockchip rk3288 pin control driver" depends on DM help - This option is to enable the AT91 pinctrl driver for AT91 PIO - controller. AT91 PIO controller is a combined gpio-controller, - pin-mux and pin-config module. Each I/O pin may be dedicated as - a general-purpose I/O or be assigned to a function of an embedded - peripheral. Each I/O pin has a glitch filter providing rejection of - glitches lower than one-half of peripheral clock cycle and - a debouncing filter providing rejection of unwanted pulses from key - or push button operations. You can also control the multi-driver - capability, pull-up and pull-down feature on each I/O pin. + Support pin multiplexing control on Rockchip rk3288 SoCs. -config PINCTRL_AT91PIO4 - bool "AT91 PIO4 pinctrl driver" - depends on DM - help - This option is to enable the AT91 pinctrl driver for AT91 PIO4 - controller which is available on SAMA5D2 SoC. + The driver is controlled by a device tree node which contains both + the GPIO definitions and pin control functions for each available + multiplex function. -config ROCKCHIP_RK3328_PINCTRL +config PINCTRL_ROCKCHIP_RK3328 bool "Rockchip rk3328 pin control driver" depends on DM help - Support pin multiplexing control on Rockchip rk3328 SoCs. The driver - is controlled by a device tree node which contains both the GPIO - definitions and pin control functions for each available multiplex - function. + Support pin multiplexing control on Rockchip rk3328 SoCs. + + The driver is controlled by a device tree node which contains both + the GPIO definitions and pin control functions for each available + multiplex function. -config ROCKCHIP_RK3399_PINCTRL +config PINCTRL_ROCKCHIP_RK3399 bool "Rockchip rk3399 pin control driver" depends on DM help - Support pin multiplexing control on Rockchip rk3399 SoCs. The driver - is controlled by a device tree node which contains both the GPIO - definitions and pin control functions for each available multiplex - function. + Support pin multiplexing control on Rockchip rk3399 SoCs. + + The driver is controlled by a device tree node which contains both + the GPIO definitions and pin control functions for each available + multiplex function. config PINCTRL_SANDBOX bool "Sandbox pinctrl driver" depends on SANDBOX help - This enables pinctrl driver for sandbox. Currently, this driver - actually does nothing but print debug messages when pinctrl - operations are invoked. + This enables pinctrl driver for sandbox. -config PIC32_PINCTRL - bool "Microchip PIC32 pin-control and pin-mux driver" - depends on DM && MACH_PIC32 - default y + Currently, this driver actually does nothing but print debug + messages when pinctrl operations are invoked. + +config PINCTRL_SINGLE + bool "Single register pin-control and pin-multiplex driver" + depends on DM help - Supports individual pin selection and configuration for each remappable - peripheral available on Microchip PIC32 SoCs. This driver is controlled - by a device tree node which contains both GPIO defintion and pin control - functions. + This enables pinctrl driver for systems using a single register for + pin configuration and multiplexing. TI's AM335X SoCs are examples of + such systems. + + Depending on the platform make sure to also enable OF_TRANSLATE and + eventually SPL_OF_TRANSLATE to get correct address translations. config PINCTRL_STI bool "STMicroelectronics STi pin-control and pin-mux driver" @@ -213,28 +233,20 @@ config PINCTRL_STI default y help Support pin multiplexing control on STMicrolectronics STi SoCs. + The driver is controlled by a device tree node which contains both - the GPIO definitions and pin control functions for each available multiplex - function. + the GPIO definitions and pin control functions for each available + multiplex function. config PINCTRL_STM32 bool "ST STM32 pin control driver" depends on DM help - Supports pin multiplexing control on stm32 SoCs. The driver is - controlled by a device tree node which contains both the GPIO - definitions and pin control functions for each available multiplex - function. + Supports pin multiplexing control on stm32 SoCs. -config PINCTRL_SINGLE - bool "Single register pin-control and pin-multiplex driver" - depends on DM - help - This enables pinctrl driver for systems using a single register for - pin configuration and multiplexing. TI's AM335X SoCs are examples of - such systems. - Depending on the platform make sure to also enable OF_TRANSLATE and - eventually SPL_OF_TRANSLATE to get correct address translations. + The driver is controlled by a device tree node which contains both + the GPIO definitions and pin control functions for each available + multiplex function. endif diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index bbb2480e865..17a7173d355 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/ -obj-$(CONFIG_PIC32_PINCTRL) += pinctrl_pic32.o +obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/ obj-$(CONFIG_PINCTRL_MESON) += meson/ obj-$(CONFIG_PINCTRL_MVEBU) += mvebu/ diff --git a/drivers/pinctrl/ath79/Makefile b/drivers/pinctrl/ath79/Makefile index dcea10ace6a..c87a9aa3e70 100644 --- a/drivers/pinctrl/ath79/Makefile +++ b/drivers/pinctrl/ath79/Makefile @@ -2,5 +2,5 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_AR933X_PINCTRL) += pinctrl_ar933x.o -obj-$(CONFIG_QCA953x_PINCTRL) += pinctrl_qca953x.o +obj-$(CONFIG_PINCTRL_AR933X) += pinctrl_ar933x.o +obj-$(CONFIG_PINCTRL_QCA953x) += pinctrl_qca953x.o diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile index b0b698ac04a..69eef4c0240 100644 --- a/drivers/pinctrl/rockchip/Makefile +++ b/drivers/pinctrl/rockchip/Makefile @@ -5,8 +5,8 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_ROCKCHIP_RK3036_PINCTRL) += pinctrl_rk3036.o -obj-$(CONFIG_ROCKCHIP_RK3188_PINCTRL) += pinctrl_rk3188.o -obj-$(CONFIG_ROCKCHIP_RK3288_PINCTRL) += pinctrl_rk3288.o -obj-$(CONFIG_ROCKCHIP_RK3328_PINCTRL) += pinctrl_rk3328.o -obj-$(CONFIG_ROCKCHIP_RK3399_PINCTRL) += pinctrl_rk3399.o +obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3036) += pinctrl_rk3036.o +obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3188) += pinctrl_rk3188.o +obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3288) += pinctrl_rk3288.o +obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3328) += pinctrl_rk3328.o +obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3399) += pinctrl_rk3399.o -- cgit v1.3.1 From ae4e4dde5246cd27d0cce29a64761c33cb4ceee4 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 27 Apr 2017 00:03:34 +0200 Subject: sunxi: power: Compile sy8106a driver only during SPL build Driver for that regulator is used only in SPL and it uses old I2C interface. If we want to use DM I2C in U-Boot proper, compilation of this driver has to be limited only to SPL. Signed-off-by: Jernej Skrabec Reviewed-by: Heiko Schocher Signed-off-by: Maxime Ripard --- drivers/power/sy8106a.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/power/sy8106a.c b/drivers/power/sy8106a.c index bbf116f6559..f9db3965f2d 100644 --- a/drivers/power/sy8106a.c +++ b/drivers/power/sy8106a.c @@ -12,6 +12,7 @@ #define SY8106A_VOUT1_SEL 1 #define SY8106A_VOUT1_SEL_ENABLE (1 << 7) +#ifdef CONFIG_SPL_BUILD static u8 sy8106a_mvolt_to_cfg(int mvolt, int min, int max, int div) { if (mvolt < min) @@ -27,3 +28,4 @@ int sy8106a_set_vout1(unsigned int mvolt) u8 data = sy8106a_mvolt_to_cfg(mvolt, 680, 1950, 10) | SY8106A_VOUT1_SEL_ENABLE; return i2c_write(SY8106A_I2C_ADDR, SY8106A_VOUT1_SEL, 1, &data, 1); } +#endif -- cgit v1.3.1 From a8f01ccff2abf680449b2e694284ecf089b5d9be Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 27 Apr 2017 00:03:36 +0200 Subject: sunxi: i2c: Add support for DM I2C This commit adds support for DM I2C on sunxi platform. It can coexist with old style sunxi I2C driver, because it is still used in SPL and by some SoCs. Because sunxi platform doesn't yet support DM clk, reset and pinctrl driver, workaround is needed to enable clocks and set resets and pinctrls. This is done by calling i2c_init_board() in board_init(). This means that CONFIG_I2Cx_ENABLE options needs to be correctly set in order to use needed I2C controller. Commit is based on the previous patch made by Philipp Tomsich Signed-off-by: Jernej Skrabec Reviewed-by: Heiko Schocher Signed-off-by: Maxime Ripard --- arch/arm/mach-sunxi/board.c | 2 ++ board/sunxi/board.c | 8 ++++++++ drivers/i2c/mvtwsi.c | 9 +++++++++ include/configs/sunxi-common.h | 4 +++- 4 files changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 4507279cc55..65b1ebd8378 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -204,7 +204,9 @@ void s_init(void) clock_init(); timer_init(); gpio_init(); +#ifndef CONFIG_DM_I2C i2c_init_board(); +#endif eth_init_board(); } diff --git a/board/sunxi/board.c b/board/sunxi/board.c index f903a5d0a02..01de42d0318 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -222,6 +222,14 @@ int board_init(void) gpio_direction_output(macpwr_pin, 1); #endif +#ifdef CONFIG_DM_I2C + /* + * Temporary workaround for enabling I2C clocks until proper sunxi DM + * clk, reset and pinctrl drivers land. + */ + i2c_init_board(); +#endif + /* Uses dm gpio code so do this here and not in i2c_init_board() */ return soft_i2c_board_init(); } diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 648a96eeb4e..3703519aa52 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -36,6 +36,14 @@ DECLARE_GLOBAL_DATA_PTR; #endif #endif /* CONFIG_DM_I2C */ +/* + * On SUNXI, we get CONFIG_SYS_TCLK from this include, so we want to + * always have it. + */ +#if defined(CONFIG_DM_I2C) && defined(CONFIG_ARCH_SUNXI) +#include +#endif + /* * TWSI register structure */ @@ -831,6 +839,7 @@ static const struct dm_i2c_ops mvtwsi_i2c_ops = { static const struct udevice_id mvtwsi_i2c_ids[] = { { .compatible = "marvell,mv64xxx-i2c", }, { .compatible = "marvell,mv78230-i2c", }, + { .compatible = "allwinner,sun6i-a31-i2c", }, { /* sentinel */ } }; diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 64a190059ac..b794e427bb8 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -211,11 +211,13 @@ #if defined CONFIG_I2C0_ENABLE || defined CONFIG_I2C1_ENABLE || \ defined CONFIG_I2C2_ENABLE || defined CONFIG_I2C3_ENABLE || \ defined CONFIG_I2C4_ENABLE || defined CONFIG_R_I2C_ENABLE -#define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MVTWSI +#ifndef CONFIG_DM_I2C +#define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_SPEED 400000 #define CONFIG_SYS_I2C_SLAVE 0x7f #endif +#endif #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD) #define CONFIG_SYS_I2C_SOFT -- cgit v1.3.1 From 56009451d843e8ccaff3408d172fe13af23e2756 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Mon, 27 Mar 2017 19:22:32 +0200 Subject: sunxi: video: Add A64/H3/H5 HDMI driver This commit adds support for HDMI output. Signed-off-by: Jernej Skrabec Reviewed-by: Simon Glass Acked-by: Maxime Ripard Signed-off-by: Maxime Ripard --- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 8 + arch/arm/include/asm/arch-sunxi/display2.h | 124 +++++++++ board/sunxi/Kconfig | 10 + drivers/video/sunxi/Makefile | 1 + drivers/video/sunxi/sunxi_de2.c | 258 ++++++++++++++++++ drivers/video/sunxi/sunxi_dw_hdmi.c | 389 ++++++++++++++++++++++++++++ include/configs/sunxi-common.h | 5 + 7 files changed, 795 insertions(+) create mode 100644 arch/arm/include/asm/arch-sunxi/display2.h create mode 100644 drivers/video/sunxi/sunxi_de2.c create mode 100644 drivers/video/sunxi/sunxi_dw_hdmi.c (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index 88c3f138173..6aa5e91adae 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -18,6 +18,8 @@ #define SUNXI_SRAM_D_BASE 0x00010000 /* 4 kiB */ #define SUNXI_SRAM_B_BASE 0x00020000 /* 64 kiB (secure) */ +#define SUNXI_DE2_BASE 0x01000000 + #ifdef CONFIG_MACH_SUN8I_A83T #define SUNXI_CPUCFG_BASE 0x01700000 #endif @@ -46,7 +48,9 @@ #define SUNXI_USB1_BASE 0x01c14000 #endif #define SUNXI_SS_BASE 0x01c15000 +#if !defined(CONFIG_MACH_SUNXI_H3_H5) && !defined(CONFIG_MACH_SUN50I) #define SUNXI_HDMI_BASE 0x01c16000 +#endif #define SUNXI_SPI2_BASE 0x01c17000 #define SUNXI_SATA_BASE 0x01c18000 #ifdef CONFIG_SUNXI_GEN_SUN4I @@ -164,6 +168,10 @@ defined(CONFIG_MACH_SUN50I) #define SUNXI_MP_BASE 0x01e80000 #define SUNXI_AVG_BASE 0x01ea0000 +#if defined(CONFIG_MACH_SUNXI_H3_H5) || defined(CONFIG_MACH_SUN50I) +#define SUNXI_HDMI_BASE 0x01ee0000 +#endif + #define SUNXI_RTC_BASE 0x01f00000 #define SUNXI_PRCM_BASE 0x01f01400 diff --git a/arch/arm/include/asm/arch-sunxi/display2.h b/arch/arm/include/asm/arch-sunxi/display2.h new file mode 100644 index 00000000000..b5875f96050 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/display2.h @@ -0,0 +1,124 @@ +/* + * Sunxi platform display controller register and constant defines + * + * (C) Copyright 2017 Jernej Skrabec + * + * Based on out of tree Linux DRM driver defines: + * Copyright (C) 2016 Jean-Francois Moine + * Copyright (c) 2016 Allwinnertech Co., Ltd. +* + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SUNXI_DISPLAY2_H +#define _SUNXI_DISPLAY2_H + +/* internal clock settings */ +struct de_clk { + u32 gate_cfg; + u32 bus_cfg; + u32 rst_cfg; + u32 div_cfg; + u32 sel_cfg; +}; + +/* global control */ +struct de_glb { + u32 ctl; + u32 status; + u32 dbuff; + u32 size; +}; + +/* alpha blending */ +struct de_bld { + u32 fcolor_ctl; + struct { + u32 fcolor; + u32 insize; + u32 offset; + u32 dum; + } attr[4]; + u32 dum0[15]; + u32 route; + u32 premultiply; + u32 bkcolor; + u32 output_size; + u32 bld_mode[4]; + u32 dum1[4]; + u32 ck_ctl; + u32 ck_cfg; + u32 dum2[2]; + u32 ck_max[4]; + u32 dum3[4]; + u32 ck_min[4]; + u32 dum4[3]; + u32 out_ctl; +}; + +/* VI channel */ +struct de_vi { + struct { + u32 attr; + u32 size; + u32 coord; + u32 pitch[3]; + u32 top_laddr[3]; + u32 bot_laddr[3]; + } cfg[4]; + u32 fcolor[4]; + u32 top_haddr[3]; + u32 bot_haddr[3]; + u32 ovl_size[2]; + u32 hori[2]; + u32 vert[2]; +}; + +struct de_ui { + struct { + u32 attr; + u32 size; + u32 coord; + u32 pitch; + u32 top_laddr; + u32 bot_laddr; + u32 fcolor; + u32 dum; + } cfg[4]; + u32 top_haddr; + u32 bot_haddr; + u32 ovl_size; +}; + +/* + * DE register constants. + */ +#define SUNXI_DE2_MUX0_BASE (SUNXI_DE2_BASE + 0x100000) +#define SUNXI_DE2_MUX1_BASE (SUNXI_DE2_BASE + 0x200000) + +#define SUNXI_DE2_MUX_GLB_REGS 0x00000 +#define SUNXI_DE2_MUX_BLD_REGS 0x01000 +#define SUNXI_DE2_MUX_CHAN_REGS 0x02000 +#define SUNXI_DE2_MUX_CHAN_SZ 0x1000 +#define SUNXI_DE2_MUX_VSU_REGS 0x20000 +#define SUNXI_DE2_MUX_GSU1_REGS 0x30000 +#define SUNXI_DE2_MUX_GSU2_REGS 0x40000 +#define SUNXI_DE2_MUX_GSU3_REGS 0x50000 +#define SUNXI_DE2_MUX_FCE_REGS 0xa0000 +#define SUNXI_DE2_MUX_BWS_REGS 0xa2000 +#define SUNXI_DE2_MUX_LTI_REGS 0xa4000 +#define SUNXI_DE2_MUX_PEAK_REGS 0xa6000 +#define SUNXI_DE2_MUX_ASE_REGS 0xa8000 +#define SUNXI_DE2_MUX_FCC_REGS 0xaa000 +#define SUNXI_DE2_MUX_DCSC_REGS 0xb0000 + +#define SUNXI_DE2_FORMAT_XRGB_8888 4 +#define SUNXI_DE2_FORMAT_RGB_565 10 + +#define SUNXI_DE2_MUX_GLB_CTL_EN (1 << 0) +#define SUNXI_DE2_UI_CFG_ATTR_EN (1 << 0) +#define SUNXI_DE2_UI_CFG_ATTR_FMT(f) ((f & 0xf) << 8) + +#define SUNXI_DE2_WH(w, h) (((h - 1) << 16) | (w - 1)) + +#endif /* _SUNXI_DISPLAY2_H */ diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 903cd482a52..ac3be300fed 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -708,6 +708,16 @@ config SUNXI_DE2 bool default n +config VIDEO_DE2 + bool "Display Engine 2 video driver" + depends on SUNXI_DE2 + select DM_VIDEO + select DISPLAY + default y + ---help--- + Say y here if you want to build DE2 video driver which is present on + newer SoCs. Currently only HDMI output is supported. + choice prompt "LCD panel support" diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile index dfc9b47a1f6..b8afd892ad7 100644 --- a/drivers/video/sunxi/Makefile +++ b/drivers/video/sunxi/Makefile @@ -6,3 +6,4 @@ # obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o ../videomodes.o +obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o lcdc.o ../dw_hdmi.o diff --git a/drivers/video/sunxi/sunxi_de2.c b/drivers/video/sunxi/sunxi_de2.c new file mode 100644 index 00000000000..9a32c3a0209 --- /dev/null +++ b/drivers/video/sunxi/sunxi_de2.c @@ -0,0 +1,258 @@ +/* + * Allwinner DE2 display driver + * + * (C) Copyright 2017 Jernej Skrabec + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +enum { + /* Maximum LCD size we support */ + LCD_MAX_WIDTH = 3840, + LCD_MAX_HEIGHT = 2160, + LCD_MAX_LOG2_BPP = VIDEO_BPP32, +}; + +static void sunxi_de2_composer_init(void) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + +#ifdef CONFIG_MACH_SUN50I + u32 reg_value; + + /* set SRAM for video use (A64 only) */ + reg_value = readl(SUNXI_SRAMC_BASE + 0x04); + reg_value &= ~(0x01 << 24); + writel(reg_value, SUNXI_SRAMC_BASE + 0x04); +#endif + + clock_set_pll10(432000000); + + /* Set DE parent to pll10 */ + clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, + CCM_DE2_CTRL_PLL10); + + /* Set ahb gating to pass */ + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE); + setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE); + + /* Clock on */ + setbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_GATE); +} + +static void sunxi_de2_mode_set(int mux, const struct display_timing *mode, + int bpp, ulong address) +{ + ulong de_mux_base = (mux == 0) ? + SUNXI_DE2_MUX0_BASE : SUNXI_DE2_MUX1_BASE; + struct de_clk * const de_clk_regs = + (struct de_clk *)(SUNXI_DE2_BASE); + struct de_glb * const de_glb_regs = + (struct de_glb *)(de_mux_base + + SUNXI_DE2_MUX_GLB_REGS); + struct de_bld * const de_bld_regs = + (struct de_bld *)(de_mux_base + + SUNXI_DE2_MUX_BLD_REGS); + struct de_ui * const de_ui_regs = + (struct de_ui *)(de_mux_base + + SUNXI_DE2_MUX_CHAN_REGS + + SUNXI_DE2_MUX_CHAN_SZ * 1); + u32 size = SUNXI_DE2_WH(mode->hactive.typ, mode->vactive.typ); + int channel; + u32 format; + + /* enable clock */ +#ifdef CONFIG_MACH_SUN8I_H3 + setbits_le32(&de_clk_regs->rst_cfg, (mux == 0) ? 1 : 4); +#else + setbits_le32(&de_clk_regs->rst_cfg, BIT(mux)); +#endif + setbits_le32(&de_clk_regs->gate_cfg, BIT(mux)); + setbits_le32(&de_clk_regs->bus_cfg, BIT(mux)); + + clrbits_le32(&de_clk_regs->sel_cfg, 1); + + writel(SUNXI_DE2_MUX_GLB_CTL_EN, &de_glb_regs->ctl); + writel(0, &de_glb_regs->status); + writel(1, &de_glb_regs->dbuff); + writel(size, &de_glb_regs->size); + + for (channel = 0; channel < 4; channel++) { + void *ch = (void *)(de_mux_base + SUNXI_DE2_MUX_CHAN_REGS + + SUNXI_DE2_MUX_CHAN_SZ * channel); + memset(ch, 0, (channel == 0) ? + sizeof(struct de_vi) : sizeof(struct de_ui)); + } + memset(de_bld_regs, 0, sizeof(struct de_bld)); + + writel(0x00000101, &de_bld_regs->fcolor_ctl); + + writel(1, &de_bld_regs->route); + + writel(0, &de_bld_regs->premultiply); + writel(0xff000000, &de_bld_regs->bkcolor); + + writel(0x03010301, &de_bld_regs->bld_mode[0]); + + writel(size, &de_bld_regs->output_size); + writel(mode->flags & DISPLAY_FLAGS_INTERLACED ? 2 : 0, + &de_bld_regs->out_ctl); + writel(0, &de_bld_regs->ck_ctl); + + writel(0xff000000, &de_bld_regs->attr[0].fcolor); + writel(size, &de_bld_regs->attr[0].insize); + + /* Disable all other units */ + writel(0, de_mux_base + SUNXI_DE2_MUX_VSU_REGS); + writel(0, de_mux_base + SUNXI_DE2_MUX_GSU1_REGS); + writel(0, de_mux_base + SUNXI_DE2_MUX_GSU2_REGS); + writel(0, de_mux_base + SUNXI_DE2_MUX_GSU3_REGS); + writel(0, de_mux_base + SUNXI_DE2_MUX_FCE_REGS); + writel(0, de_mux_base + SUNXI_DE2_MUX_BWS_REGS); + writel(0, de_mux_base + SUNXI_DE2_MUX_LTI_REGS); + writel(0, de_mux_base + SUNXI_DE2_MUX_PEAK_REGS); + writel(0, de_mux_base + SUNXI_DE2_MUX_ASE_REGS); + writel(0, de_mux_base + SUNXI_DE2_MUX_FCC_REGS); + writel(0, de_mux_base + SUNXI_DE2_MUX_DCSC_REGS); + + switch (bpp) { + case 16: + format = SUNXI_DE2_UI_CFG_ATTR_FMT(SUNXI_DE2_FORMAT_RGB_565); + break; + case 32: + default: + format = SUNXI_DE2_UI_CFG_ATTR_FMT(SUNXI_DE2_FORMAT_XRGB_8888); + break; + } + + writel(SUNXI_DE2_UI_CFG_ATTR_EN | format, &de_ui_regs->cfg[0].attr); + writel(size, &de_ui_regs->cfg[0].size); + writel(0, &de_ui_regs->cfg[0].coord); + writel((bpp / 8) * mode->hactive.typ, &de_ui_regs->cfg[0].pitch); + writel(address, &de_ui_regs->cfg[0].top_laddr); + writel(size, &de_ui_regs->ovl_size); + + /* apply settings */ + writel(1, &de_glb_regs->dbuff); +} + +static int sunxi_de2_init(struct udevice *dev, ulong fbbase, + enum video_log2_bpp l2bpp, + struct udevice *disp, int mux) +{ + struct video_priv *uc_priv = dev_get_uclass_priv(dev); + struct display_timing timing; + struct display_plat *disp_uc_plat; + int ret; + + disp_uc_plat = dev_get_uclass_platdata(disp); + debug("Using device '%s', disp_uc_priv=%p\n", disp->name, disp_uc_plat); + if (display_in_use(disp)) { + debug(" - device in use\n"); + return -EBUSY; + } + + disp_uc_plat->source_id = mux; + + ret = device_probe(disp); + if (ret) { + debug("%s: device '%s' display won't probe (ret=%d)\n", + __func__, dev->name, ret); + return ret; + } + + ret = display_read_timing(disp, &timing); + if (ret) { + debug("%s: Failed to read timings\n", __func__); + return ret; + } + + sunxi_de2_composer_init(); + sunxi_de2_mode_set(mux, &timing, 1 << l2bpp, fbbase); + + ret = display_enable(disp, 1 << l2bpp, &timing); + if (ret) { + debug("%s: Failed to enable display\n", __func__); + return ret; + } + + uc_priv->xsize = timing.hactive.typ; + uc_priv->ysize = timing.vactive.typ; + uc_priv->bpix = l2bpp; + debug("fb=%lx, size=%d %d\n", fbbase, uc_priv->xsize, uc_priv->ysize); + + return 0; +} + +static int sunxi_de2_probe(struct udevice *dev) +{ + struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); + struct udevice *disp; + int ret; + int mux; + + /* Before relocation we don't need to do anything */ + if (!(gd->flags & GD_FLG_RELOC)) + return 0; + + ret = uclass_find_device_by_name(UCLASS_DISPLAY, + "sunxi_dw_hdmi", &disp); + if (ret) { + debug("%s: hdmi display not found (ret=%d)\n", __func__, ret); + return ret; + } + + if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5)) + mux = 0; + else + mux = 1; + + ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux); + if (ret) + return ret; + + video_set_flush_dcache(dev, 1); + + return 0; +} + +static int sunxi_de2_bind(struct udevice *dev) +{ + struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); + + plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT * + (1 << LCD_MAX_LOG2_BPP) / 8; + + return 0; +} + +static const struct video_ops sunxi_de2_ops = { +}; + +U_BOOT_DRIVER(sunxi_de2) = { + .name = "sunxi_de2", + .id = UCLASS_VIDEO, + .ops = &sunxi_de2_ops, + .bind = sunxi_de2_bind, + .probe = sunxi_de2_probe, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DEVICE(sunxi_de2) = { + .name = "sunxi_de2" +}; diff --git a/drivers/video/sunxi/sunxi_dw_hdmi.c b/drivers/video/sunxi/sunxi_dw_hdmi.c new file mode 100644 index 00000000000..33920a2b676 --- /dev/null +++ b/drivers/video/sunxi/sunxi_dw_hdmi.c @@ -0,0 +1,389 @@ +/* + * Allwinner DW HDMI bridge + * + * (C) Copyright 2017 Jernej Skrabec + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct sunxi_dw_hdmi_priv { + struct dw_hdmi hdmi; + int mux; +}; + +struct sunxi_hdmi_phy { + u32 pol; + u32 res1[3]; + u32 read_en; + u32 unscramble; + u32 res2[2]; + u32 ctrl; + u32 unk1; + u32 unk2; + u32 pll; + u32 clk; + u32 unk3; + u32 status; +}; + +#define HDMI_PHY_OFFS 0x10000 + +static int sunxi_dw_hdmi_get_divider(uint clock) +{ + /* + * Due to missing documentaion of HDMI PHY, we know correct + * settings only for following four PHY dividers. Select one + * based on clock speed. + */ + if (clock <= 27000000) + return 11; + else if (clock <= 74250000) + return 4; + else if (clock <= 148500000) + return 2; + else + return 1; +} + +static void sunxi_dw_hdmi_phy_init(void) +{ + struct sunxi_hdmi_phy * const phy = + (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); + unsigned long tmo; + u32 tmp; + + /* + * HDMI PHY settings are taken as-is from Allwinner BSP code. + * There is no documentation. + */ + writel(0, &phy->ctrl); + setbits_le32(&phy->ctrl, BIT(0)); + udelay(5); + setbits_le32(&phy->ctrl, BIT(16)); + setbits_le32(&phy->ctrl, BIT(1)); + udelay(10); + setbits_le32(&phy->ctrl, BIT(2)); + udelay(5); + setbits_le32(&phy->ctrl, BIT(3)); + udelay(40); + setbits_le32(&phy->ctrl, BIT(19)); + udelay(100); + setbits_le32(&phy->ctrl, BIT(18)); + setbits_le32(&phy->ctrl, 7 << 4); + + /* Note that Allwinner code doesn't fail in case of timeout */ + tmo = timer_get_us() + 2000; + while ((readl(&phy->status) & 0x80) == 0) { + if (timer_get_us() > tmo) { + printf("Warning: HDMI PHY init timeout!\n"); + break; + } + } + + setbits_le32(&phy->ctrl, 0xf << 8); + setbits_le32(&phy->ctrl, BIT(7)); + + writel(0x39dc5040, &phy->pll); + writel(0x80084343, &phy->clk); + udelay(10000); + writel(1, &phy->unk3); + setbits_le32(&phy->pll, BIT(25)); + udelay(100000); + tmp = (readl(&phy->status) & 0x1f800) >> 11; + setbits_le32(&phy->pll, BIT(31) | BIT(30)); + setbits_le32(&phy->pll, tmp); + writel(0x01FF0F7F, &phy->ctrl); + writel(0x80639000, &phy->unk1); + writel(0x0F81C405, &phy->unk2); + + /* enable read access to HDMI controller */ + writel(0x54524545, &phy->read_en); + /* descramble register offsets */ + writel(0x42494E47, &phy->unscramble); +} + +static int sunxi_dw_hdmi_get_plug_in_status(void) +{ + struct sunxi_hdmi_phy * const phy = + (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); + + return !!(readl(&phy->status) & (1 << 19)); +} + +static int sunxi_dw_hdmi_wait_for_hpd(void) +{ + ulong start; + + start = get_timer(0); + do { + if (sunxi_dw_hdmi_get_plug_in_status()) + return 0; + udelay(100); + } while (get_timer(start) < 300); + + return -1; +} + +static void sunxi_dw_hdmi_phy_set(uint clock) +{ + struct sunxi_hdmi_phy * const phy = + (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); + int div = sunxi_dw_hdmi_get_divider(clock); + u32 tmp; + + /* + * Unfortunately, we don't know much about those magic + * numbers. They are taken from Allwinner BSP driver. + */ + switch (div) { + case 1: + writel(0x30dc5fc0, &phy->pll); + writel(0x800863C0, &phy->clk); + mdelay(10); + writel(0x00000001, &phy->unk3); + setbits_le32(&phy->pll, BIT(25)); + mdelay(200); + tmp = (readl(&phy->status) & 0x1f800) >> 11; + setbits_le32(&phy->pll, BIT(31) | BIT(30)); + if (tmp < 0x3d) + setbits_le32(&phy->pll, tmp + 2); + else + setbits_le32(&phy->pll, 0x3f); + mdelay(100); + writel(0x01FFFF7F, &phy->ctrl); + writel(0x8063b000, &phy->unk1); + writel(0x0F8246B5, &phy->unk2); + break; + case 2: + writel(0x39dc5040, &phy->pll); + writel(0x80084381, &phy->clk); + mdelay(10); + writel(0x00000001, &phy->unk3); + setbits_le32(&phy->pll, BIT(25)); + mdelay(100); + tmp = (readl(&phy->status) & 0x1f800) >> 11; + setbits_le32(&phy->pll, BIT(31) | BIT(30)); + setbits_le32(&phy->pll, tmp); + writel(0x01FFFF7F, &phy->ctrl); + writel(0x8063a800, &phy->unk1); + writel(0x0F81C485, &phy->unk2); + break; + case 4: + writel(0x39dc5040, &phy->pll); + writel(0x80084343, &phy->clk); + mdelay(10); + writel(0x00000001, &phy->unk3); + setbits_le32(&phy->pll, BIT(25)); + mdelay(100); + tmp = (readl(&phy->status) & 0x1f800) >> 11; + setbits_le32(&phy->pll, BIT(31) | BIT(30)); + setbits_le32(&phy->pll, tmp); + writel(0x01FFFF7F, &phy->ctrl); + writel(0x8063b000, &phy->unk1); + writel(0x0F81C405, &phy->unk2); + break; + case 11: + writel(0x39dc5040, &phy->pll); + writel(0x8008430a, &phy->clk); + mdelay(10); + writel(0x00000001, &phy->unk3); + setbits_le32(&phy->pll, BIT(25)); + mdelay(100); + tmp = (readl(&phy->status) & 0x1f800) >> 11; + setbits_le32(&phy->pll, BIT(31) | BIT(30)); + setbits_le32(&phy->pll, tmp); + writel(0x01FFFF7F, &phy->ctrl); + writel(0x8063b000, &phy->unk1); + writel(0x0F81C405, &phy->unk2); + break; + } +} + +static void sunxi_dw_hdmi_pll_set(uint clk_khz) +{ + int value, n, m, div = 0, diff; + int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF; + + div = sunxi_dw_hdmi_get_divider(clk_khz * 1000); + + /* + * Find the lowest divider resulting in a matching clock. If there + * is no match, pick the closest lower clock, as monitors tend to + * not sync to higher frequencies. + */ + for (m = 1; m <= 16; m++) { + n = (m * div * clk_khz) / 24000; + + if ((n >= 1) && (n <= 128)) { + value = (24000 * n) / m / div; + diff = clk_khz - value; + if (diff < best_diff) { + best_diff = diff; + best_m = m; + best_n = n; + } + } + } + + clock_set_pll3_factors(best_m, best_n); + debug("dotclock: %dkHz = %dkHz: (24MHz * %d) / %d / %d\n", + clk_khz, (clock_get_pll3() / 1000) / div, + best_n, best_m, div); +} + +static void sunxi_dw_hdmi_lcdc_init(int mux, const struct display_timing *edid, + int bpp) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + int div = sunxi_dw_hdmi_get_divider(edid->pixelclock.typ); + struct sunxi_lcdc_reg *lcdc; + + if (mux == 0) { + lcdc = (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; + + /* Reset off */ + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD0); + + /* Clock on */ + setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD0); + writel(CCM_LCD0_CTRL_GATE | CCM_LCD0_CTRL_M(div), + &ccm->lcd0_clk_cfg); + } else { + lcdc = (struct sunxi_lcdc_reg *)SUNXI_LCD1_BASE; + + /* Reset off */ + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD1); + + /* Clock on */ + setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD1); + writel(CCM_LCD1_CTRL_GATE | CCM_LCD1_CTRL_M(div), + &ccm->lcd1_clk_cfg); + } + + lcdc_init(lcdc); + lcdc_tcon1_mode_set(lcdc, edid, false, false); + lcdc_enable(lcdc, bpp); +} + +static int sunxi_dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock) +{ + sunxi_dw_hdmi_pll_set(mpixelclock/1000); + sunxi_dw_hdmi_phy_set(mpixelclock); + + return 0; +} + +static int sunxi_dw_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size) +{ + struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev); + + return dw_hdmi_read_edid(&priv->hdmi, buf, buf_size); +} + +static int sunxi_dw_hdmi_enable(struct udevice *dev, int panel_bpp, + const struct display_timing *edid) +{ + struct sunxi_hdmi_phy * const phy = + (struct sunxi_hdmi_phy *)(SUNXI_HDMI_BASE + HDMI_PHY_OFFS); + struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev); + int ret; + + ret = dw_hdmi_enable(&priv->hdmi, edid); + if (ret) + return ret; + + sunxi_dw_hdmi_lcdc_init(priv->mux, edid, panel_bpp); + + /* + * Condition in original code is a bit weird. This is attempt + * to make it more reasonable and it works. It could be that + * bits and conditions are related and should be separated. + */ + if (!((edid->flags & DISPLAY_FLAGS_HSYNC_HIGH) && + (edid->flags & DISPLAY_FLAGS_VSYNC_HIGH))) { + setbits_le32(&phy->pol, 0x300); + } + + setbits_le32(&phy->ctrl, 0xf << 12); + + /* + * This is last hdmi access before boot, so scramble addresses + * again or othwerwise BSP driver won't work. Dummy read is + * needed or otherwise last write doesn't get written correctly. + */ + (void)readb(SUNXI_HDMI_BASE); + writel(0, &phy->unscramble); + + return 0; +} + +static int sunxi_dw_hdmi_probe(struct udevice *dev) +{ + struct display_plat *uc_plat = dev_get_uclass_platdata(dev); + struct sunxi_dw_hdmi_priv *priv = dev_get_priv(dev); + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + int ret; + + /* Set pll3 to 297 MHz */ + clock_set_pll3(297000000); + + /* Set hdmi parent to pll3 */ + clrsetbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_PLL_MASK, + CCM_HDMI_CTRL_PLL3); + + /* Set ahb gating to pass */ + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI); + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI2); + setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI); + setbits_le32(&ccm->hdmi_slow_clk_cfg, CCM_HDMI_SLOW_CTRL_DDC_GATE); + + /* Clock on */ + setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE); + + sunxi_dw_hdmi_phy_init(); + + ret = sunxi_dw_hdmi_wait_for_hpd(); + if (ret < 0) { + debug("hdmi can not get hpd signal\n"); + return -1; + } + + priv->hdmi.ioaddr = SUNXI_HDMI_BASE; + priv->hdmi.i2c_clk_high = 0xd8; + priv->hdmi.i2c_clk_low = 0xfe; + priv->hdmi.reg_io_width = 1; + priv->hdmi.phy_set = sunxi_dw_hdmi_phy_cfg; + priv->mux = uc_plat->source_id; + + dw_hdmi_init(&priv->hdmi); + + return 0; +} + +static const struct dm_display_ops sunxi_dw_hdmi_ops = { + .read_edid = sunxi_dw_hdmi_read_edid, + .enable = sunxi_dw_hdmi_enable, +}; + +U_BOOT_DRIVER(sunxi_dw_hdmi) = { + .name = "sunxi_dw_hdmi", + .id = UCLASS_DISPLAY, + .ops = &sunxi_dw_hdmi_ops, + .probe = sunxi_dw_hdmi_probe, + .priv_auto_alloc_size = sizeof(struct sunxi_dw_hdmi_priv), +}; + +U_BOOT_DEVICE(sunxi_dw_hdmi) = { + .name = "sunxi_dw_hdmi" +}; diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index b794e427bb8..997a92c8be0 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -475,6 +475,11 @@ extern int soft_i2c_gpio_scl; #define CONSOLE_STDOUT_SETTINGS \ "stdout=serial,vga\0" \ "stderr=serial,vga\0" +#elif CONFIG_DM_VIDEO +#define CONFIG_SYS_WHITE_ON_BLACK +#define CONSOLE_STDOUT_SETTINGS \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" #else #define CONSOLE_STDOUT_SETTINGS \ "stdout=serial\0" \ -- cgit v1.3.1 From 56aceaf2828ea3471fec99916c6c6558a309fb82 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 26 Apr 2017 22:27:44 -0600 Subject: power: Rename CONFIG_AS3722_POWER to CONFIG_PMIC_AS3722 Before converting this to Kconfig, rename it to match the other PMICs. Signed-off-by: Simon Glass --- arch/arm/mach-tegra/board2.c | 2 +- drivers/power/Makefile | 2 +- include/configs/apalis-tk1.h | 2 +- include/configs/cei-tk1-som.h | 2 +- include/configs/jetson-tk1.h | 2 +- include/configs/nyan-big.h | 2 +- scripts/config_whitelist.txt | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c index b73cd632e7d..84f1ee5035f 100644 --- a/arch/arm/mach-tegra/board2.c +++ b/arch/arm/mach-tegra/board2.c @@ -148,7 +148,7 @@ int board_init(void) debug("Memory controller init failed: %d\n", err); # endif # endif /* CONFIG_TEGRA_PMU */ -#ifdef CONFIG_AS3722_POWER +#ifdef CONFIG_PMIC_AS3722 err = as3722_init(NULL); if (err && err != -ENODEV) return err; diff --git a/drivers/power/Makefile b/drivers/power/Makefile index b43523e6282..29e135756ba 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -5,7 +5,7 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_AS3722_POWER) += as3722.o +obj-$(CONFIG_PMIC_AS3722) += as3722.o obj-$(CONFIG_AXP152_POWER) += axp152.o obj-$(CONFIG_AXP209_POWER) += axp209.o obj-$(CONFIG_AXP221_POWER) += axp221.o diff --git a/include/configs/apalis-tk1.h b/include/configs/apalis-tk1.h index 84652decd63..a64037b5954 100644 --- a/include/configs/apalis-tk1.h +++ b/include/configs/apalis-tk1.h @@ -12,7 +12,7 @@ #include /* enable PMIC */ -#define CONFIG_AS3722_POWER +#define CONFIG_PMIC_AS3722 #include "tegra124-common.h" diff --git a/include/configs/cei-tk1-som.h b/include/configs/cei-tk1-som.h index 5ec63cd8bec..de56920fe99 100644 --- a/include/configs/cei-tk1-som.h +++ b/include/configs/cei-tk1-som.h @@ -15,7 +15,7 @@ #include /* enable PMIC */ -#define CONFIG_AS3722_POWER +#define CONFIG_PMIC_AS3722 #include "tegra124-common.h" diff --git a/include/configs/jetson-tk1.h b/include/configs/jetson-tk1.h index 7c0456c5ce3..5482f55ce0a 100644 --- a/include/configs/jetson-tk1.h +++ b/include/configs/jetson-tk1.h @@ -11,7 +11,7 @@ #include /* enable PMIC */ -#define CONFIG_AS3722_POWER +#define CONFIG_PMIC_AS3722 #include "tegra124-common.h" diff --git a/include/configs/nyan-big.h b/include/configs/nyan-big.h index acf9d66ae04..906423dba94 100644 --- a/include/configs/nyan-big.h +++ b/include/configs/nyan-big.h @@ -31,7 +31,7 @@ #define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) /* LCD support */ -#define CONFIG_AS3722_POWER +#define CONFIG_PMIC_AS3722 #define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_CMD_BMP diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index cad6117034c..1349fb0f7d8 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -147,7 +147,6 @@ CONFIG_ARM_PL180_MMCI_BASE CONFIG_ARM_PL180_MMCI_CLOCK_FREQ CONFIG_ARM_THUMB CONFIG_ARP_TIMEOUT -CONFIG_AS3722_POWER CONFIG_ASTRO5373L CONFIG_ASTRO_COFDMDUOS2 CONFIG_ASTRO_TWIN7S2 @@ -2231,6 +2230,7 @@ CONFIG_PMECC_INDEX_TABLE_OFFSET CONFIG_PMECC_SECTOR_SIZE CONFIG_PME_PLAT_CLK_DIV CONFIG_PMIC +CONFIG_PMIC_AS3722 CONFIG_PMU CONFIG_PMW_BASE CONFIG_PM_SLEEP -- cgit v1.3.1 From 2838c07f47016fe632273f5f799a4cefa7341b41 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 26 Apr 2017 22:27:45 -0600 Subject: power: Move as3722 pmic to pmic/ directory Most of the PMICs are in the drivers/power/pmic/ directory. Move this one there. Signed-off-by: Simon Glass --- drivers/power/Makefile | 1 - drivers/power/as3722.c | 274 -------------------------------------------- drivers/power/pmic/Makefile | 1 + drivers/power/pmic/as3722.c | 274 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 275 insertions(+), 275 deletions(-) delete mode 100644 drivers/power/as3722.c create mode 100644 drivers/power/pmic/as3722.c (limited to 'drivers') diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 29e135756ba..90a3b00a7cf 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -5,7 +5,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-$(CONFIG_PMIC_AS3722) += as3722.o obj-$(CONFIG_AXP152_POWER) += axp152.o obj-$(CONFIG_AXP209_POWER) += axp209.o obj-$(CONFIG_AXP221_POWER) += axp221.o diff --git a/drivers/power/as3722.c b/drivers/power/as3722.c deleted file mode 100644 index c09e1de06f4..00000000000 --- a/drivers/power/as3722.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2014 NVIDIA Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#define pr_fmt(fmt) "as3722: " fmt - -#include -#include -#include -#include -#include - -#include - -#define AS3722_SD_VOLTAGE(n) (0x00 + (n)) -#define AS3722_GPIO_CONTROL(n) (0x08 + (n)) -#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH (1 << 0) -#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL (7 << 0) -#define AS3722_GPIO_CONTROL_INVERT (1 << 7) -#define AS3722_LDO_VOLTAGE(n) (0x10 + (n)) -#define AS3722_GPIO_SIGNAL_OUT 0x20 -#define AS3722_SD_CONTROL 0x4d -#define AS3722_LDO_CONTROL 0x4e -#define AS3722_ASIC_ID1 0x90 -#define AS3722_DEVICE_ID 0x0c -#define AS3722_ASIC_ID2 0x91 - -int as3722_read(struct udevice *pmic, u8 reg, u8 *value) -{ - int err; - - err = dm_i2c_read(pmic, reg, value, 1); - if (err < 0) - return err; - - return 0; -} - -int as3722_write(struct udevice *pmic, u8 reg, u8 value) -{ - int err; - - err = dm_i2c_write(pmic, reg, &value, 1); - if (err < 0) - return err; - - return 0; -} - -static int as3722_read_id(struct udevice *pmic, u8 *id, u8 *revision) -{ - int err; - - err = as3722_read(pmic, AS3722_ASIC_ID1, id); - if (err) { - error("failed to read ID1 register: %d", err); - return err; - } - - err = as3722_read(pmic, AS3722_ASIC_ID2, revision); - if (err) { - error("failed to read ID2 register: %d", err); - return err; - } - - return 0; -} - -int as3722_sd_enable(struct udevice *pmic, unsigned int sd) -{ - u8 value; - int err; - - if (sd > 6) - return -EINVAL; - - err = as3722_read(pmic, AS3722_SD_CONTROL, &value); - if (err) { - error("failed to read SD control register: %d", err); - return err; - } - - value |= 1 << sd; - - err = as3722_write(pmic, AS3722_SD_CONTROL, value); - if (err < 0) { - error("failed to write SD control register: %d", err); - return err; - } - - return 0; -} - -int as3722_sd_set_voltage(struct udevice *pmic, unsigned int sd, u8 value) -{ - int err; - - if (sd > 6) - return -EINVAL; - - err = as3722_write(pmic, AS3722_SD_VOLTAGE(sd), value); - if (err < 0) { - error("failed to write SD%u voltage register: %d", sd, err); - return err; - } - - return 0; -} - -int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo) -{ - u8 value; - int err; - - if (ldo > 11) - return -EINVAL; - - err = as3722_read(pmic, AS3722_LDO_CONTROL, &value); - if (err) { - error("failed to read LDO control register: %d", err); - return err; - } - - value |= 1 << ldo; - - err = as3722_write(pmic, AS3722_LDO_CONTROL, value); - if (err < 0) { - error("failed to write LDO control register: %d", err); - return err; - } - - return 0; -} - -int as3722_ldo_set_voltage(struct udevice *pmic, unsigned int ldo, u8 value) -{ - int err; - - if (ldo > 11) - return -EINVAL; - - err = as3722_write(pmic, AS3722_LDO_VOLTAGE(ldo), value); - if (err < 0) { - error("failed to write LDO%u voltage register: %d", ldo, - err); - return err; - } - - return 0; -} - -int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, - unsigned long flags) -{ - u8 value = 0; - int err; - - if (flags & AS3722_GPIO_OUTPUT_VDDH) - value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; - - if (flags & AS3722_GPIO_INVERT) - value |= AS3722_GPIO_CONTROL_INVERT; - - err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value); - if (err) { - error("failed to configure GPIO#%u: %d", gpio, err); - return err; - } - - return 0; -} - -static int as3722_gpio_set(struct udevice *pmic, unsigned int gpio, - unsigned int level) -{ - const char *l; - u8 value; - int err; - - if (gpio > 7) - return -EINVAL; - - err = as3722_read(pmic, AS3722_GPIO_SIGNAL_OUT, &value); - if (err < 0) { - error("failed to read GPIO signal out register: %d", err); - return err; - } - - if (level == 0) { - value &= ~(1 << gpio); - l = "low"; - } else { - value |= 1 << gpio; - l = "high"; - } - - err = as3722_write(pmic, AS3722_GPIO_SIGNAL_OUT, value); - if (err) { - error("failed to set GPIO#%u %s: %d", gpio, l, err); - return err; - } - - return 0; -} - -int as3722_gpio_direction_output(struct udevice *pmic, unsigned int gpio, - unsigned int level) -{ - u8 value; - int err; - - if (gpio > 7) - return -EINVAL; - - if (level == 0) - value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL; - else - value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; - - err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value); - if (err) { - error("failed to configure GPIO#%u as output: %d", gpio, err); - return err; - } - - err = as3722_gpio_set(pmic, gpio, level); - if (err < 0) { - error("failed to set GPIO#%u high: %d", gpio, err); - return err; - } - - return 0; -} - -/* Temporary function until we get the pmic framework */ -int as3722_get(struct udevice **devp) -{ - int bus = 0; - int address = 0x40; - - return i2c_get_chip_for_busnum(bus, address, 1, devp); -} - -int as3722_init(struct udevice **devp) -{ - struct udevice *pmic; - u8 id, revision; - const unsigned int bus = 0; - const unsigned int address = 0x40; - int err; - - err = i2c_get_chip_for_busnum(bus, address, 1, &pmic); - if (err) - return err; - err = as3722_read_id(pmic, &id, &revision); - if (err < 0) { - error("failed to read ID: %d", err); - return err; - } - - if (id != AS3722_DEVICE_ID) { - error("unknown device"); - return -ENOENT; - } - - debug("AS3722 revision %#x found on I2C bus %u, address %#x\n", - revision, bus, address); - if (devp) - *devp = pmic; - - return 0; -} diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 40240c79362..5f1bef33cdd 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o obj-$(CONFIG_PMIC_ACT8846) += act8846.o +obj-$(CONFIG_PMIC_AS3722) += as3722.o obj-$(CONFIG_PMIC_MAX8997) += max8997.o obj-$(CONFIG_PMIC_PM8916) += pm8916.o obj-$(CONFIG_PMIC_RK808) += rk808.o diff --git a/drivers/power/pmic/as3722.c b/drivers/power/pmic/as3722.c new file mode 100644 index 00000000000..c09e1de06f4 --- /dev/null +++ b/drivers/power/pmic/as3722.c @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2014 NVIDIA Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define pr_fmt(fmt) "as3722: " fmt + +#include +#include +#include +#include +#include + +#include + +#define AS3722_SD_VOLTAGE(n) (0x00 + (n)) +#define AS3722_GPIO_CONTROL(n) (0x08 + (n)) +#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH (1 << 0) +#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL (7 << 0) +#define AS3722_GPIO_CONTROL_INVERT (1 << 7) +#define AS3722_LDO_VOLTAGE(n) (0x10 + (n)) +#define AS3722_GPIO_SIGNAL_OUT 0x20 +#define AS3722_SD_CONTROL 0x4d +#define AS3722_LDO_CONTROL 0x4e +#define AS3722_ASIC_ID1 0x90 +#define AS3722_DEVICE_ID 0x0c +#define AS3722_ASIC_ID2 0x91 + +int as3722_read(struct udevice *pmic, u8 reg, u8 *value) +{ + int err; + + err = dm_i2c_read(pmic, reg, value, 1); + if (err < 0) + return err; + + return 0; +} + +int as3722_write(struct udevice *pmic, u8 reg, u8 value) +{ + int err; + + err = dm_i2c_write(pmic, reg, &value, 1); + if (err < 0) + return err; + + return 0; +} + +static int as3722_read_id(struct udevice *pmic, u8 *id, u8 *revision) +{ + int err; + + err = as3722_read(pmic, AS3722_ASIC_ID1, id); + if (err) { + error("failed to read ID1 register: %d", err); + return err; + } + + err = as3722_read(pmic, AS3722_ASIC_ID2, revision); + if (err) { + error("failed to read ID2 register: %d", err); + return err; + } + + return 0; +} + +int as3722_sd_enable(struct udevice *pmic, unsigned int sd) +{ + u8 value; + int err; + + if (sd > 6) + return -EINVAL; + + err = as3722_read(pmic, AS3722_SD_CONTROL, &value); + if (err) { + error("failed to read SD control register: %d", err); + return err; + } + + value |= 1 << sd; + + err = as3722_write(pmic, AS3722_SD_CONTROL, value); + if (err < 0) { + error("failed to write SD control register: %d", err); + return err; + } + + return 0; +} + +int as3722_sd_set_voltage(struct udevice *pmic, unsigned int sd, u8 value) +{ + int err; + + if (sd > 6) + return -EINVAL; + + err = as3722_write(pmic, AS3722_SD_VOLTAGE(sd), value); + if (err < 0) { + error("failed to write SD%u voltage register: %d", sd, err); + return err; + } + + return 0; +} + +int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo) +{ + u8 value; + int err; + + if (ldo > 11) + return -EINVAL; + + err = as3722_read(pmic, AS3722_LDO_CONTROL, &value); + if (err) { + error("failed to read LDO control register: %d", err); + return err; + } + + value |= 1 << ldo; + + err = as3722_write(pmic, AS3722_LDO_CONTROL, value); + if (err < 0) { + error("failed to write LDO control register: %d", err); + return err; + } + + return 0; +} + +int as3722_ldo_set_voltage(struct udevice *pmic, unsigned int ldo, u8 value) +{ + int err; + + if (ldo > 11) + return -EINVAL; + + err = as3722_write(pmic, AS3722_LDO_VOLTAGE(ldo), value); + if (err < 0) { + error("failed to write LDO%u voltage register: %d", ldo, + err); + return err; + } + + return 0; +} + +int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, + unsigned long flags) +{ + u8 value = 0; + int err; + + if (flags & AS3722_GPIO_OUTPUT_VDDH) + value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; + + if (flags & AS3722_GPIO_INVERT) + value |= AS3722_GPIO_CONTROL_INVERT; + + err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value); + if (err) { + error("failed to configure GPIO#%u: %d", gpio, err); + return err; + } + + return 0; +} + +static int as3722_gpio_set(struct udevice *pmic, unsigned int gpio, + unsigned int level) +{ + const char *l; + u8 value; + int err; + + if (gpio > 7) + return -EINVAL; + + err = as3722_read(pmic, AS3722_GPIO_SIGNAL_OUT, &value); + if (err < 0) { + error("failed to read GPIO signal out register: %d", err); + return err; + } + + if (level == 0) { + value &= ~(1 << gpio); + l = "low"; + } else { + value |= 1 << gpio; + l = "high"; + } + + err = as3722_write(pmic, AS3722_GPIO_SIGNAL_OUT, value); + if (err) { + error("failed to set GPIO#%u %s: %d", gpio, l, err); + return err; + } + + return 0; +} + +int as3722_gpio_direction_output(struct udevice *pmic, unsigned int gpio, + unsigned int level) +{ + u8 value; + int err; + + if (gpio > 7) + return -EINVAL; + + if (level == 0) + value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL; + else + value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; + + err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value); + if (err) { + error("failed to configure GPIO#%u as output: %d", gpio, err); + return err; + } + + err = as3722_gpio_set(pmic, gpio, level); + if (err < 0) { + error("failed to set GPIO#%u high: %d", gpio, err); + return err; + } + + return 0; +} + +/* Temporary function until we get the pmic framework */ +int as3722_get(struct udevice **devp) +{ + int bus = 0; + int address = 0x40; + + return i2c_get_chip_for_busnum(bus, address, 1, devp); +} + +int as3722_init(struct udevice **devp) +{ + struct udevice *pmic; + u8 id, revision; + const unsigned int bus = 0; + const unsigned int address = 0x40; + int err; + + err = i2c_get_chip_for_busnum(bus, address, 1, &pmic); + if (err) + return err; + err = as3722_read_id(pmic, &id, &revision); + if (err < 0) { + error("failed to read ID: %d", err); + return err; + } + + if (id != AS3722_DEVICE_ID) { + error("unknown device"); + return -ENOENT; + } + + debug("AS3722 revision %#x found on I2C bus %u, address %#x\n", + revision, bus, address); + if (devp) + *devp = pmic; + + return 0; +} -- cgit v1.3.1 From bdf25a5e04078951e5b7fef4f4c432e88263244f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 26 Apr 2017 22:27:46 -0600 Subject: power: Convert CONFIG_PMIC_AS3722 to Kconfig This converts the following to Kconfig: CONFIG_PMIC_AS3722 Signed-off-by: Simon Glass --- configs/apalis-tk1_defconfig | 1 + configs/cei-tk1-som_defconfig | 1 + configs/jetson-tk1_defconfig | 1 + configs/nyan-big_defconfig | 1 + drivers/power/pmic/Kconfig | 8 ++++++++ include/configs/apalis-tk1.h | 3 --- include/configs/cei-tk1-som.h | 3 --- include/configs/jetson-tk1.h | 3 --- include/configs/nyan-big.h | 1 - scripts/config_whitelist.txt | 1 - 10 files changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/configs/apalis-tk1_defconfig b/configs/apalis-tk1_defconfig index 10862e56e75..648be92fcbb 100644 --- a/configs/apalis-tk1_defconfig +++ b/configs/apalis-tk1_defconfig @@ -34,6 +34,7 @@ CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_TEGRA=y +CONFIG_PMIC_AS3722=y CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/cei-tk1-som_defconfig b/configs/cei-tk1-som_defconfig index 88b93cb0ffa..dd6fd498b7f 100644 --- a/configs/cei-tk1-som_defconfig +++ b/configs/cei-tk1-som_defconfig @@ -38,6 +38,7 @@ CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_TEGRA=y +CONFIG_PMIC_AS3722=y CONFIG_SYS_NS16550=y CONFIG_TEGRA114_SPI=y CONFIG_USB=y diff --git a/configs/jetson-tk1_defconfig b/configs/jetson-tk1_defconfig index 58d41846007..2c3f1748d8f 100644 --- a/configs/jetson-tk1_defconfig +++ b/configs/jetson-tk1_defconfig @@ -38,6 +38,7 @@ CONFIG_PCI=y CONFIG_DM_PCI=y CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_TEGRA=y +CONFIG_PMIC_AS3722=y CONFIG_SYS_NS16550=y CONFIG_TEGRA114_SPI=y CONFIG_USB=y diff --git a/configs/nyan-big_defconfig b/configs/nyan-big_defconfig index 63f1a6f03f9..b132eb1f601 100644 --- a/configs/nyan-big_defconfig +++ b/configs/nyan-big_defconfig @@ -42,6 +42,7 @@ CONFIG_CROS_EC_SPI=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_DM_PMIC=y +CONFIG_PMIC_AS3722=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_PWM_TEGRA=y diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 03fea078daa..4891b1704e8 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -40,6 +40,14 @@ config PMIC_ACT8846 functions. It uses an I2C interface and is designed for use with tablets and smartphones. +config PMIC_AS3722 + bool "Enable support for the Austria Micro Systems (AMS) AS7322 PMIC" + help + The AS3722 includes 7 DC/DC buck convertors, 11 low-noise LDOs, a + real-time clock, GPIOs, ADC and a few other features. It uses an I2C + interface and is designs to cover most of the power managementment + required for a tablets or laptop. + config DM_PMIC_PFUZE100 bool "Enable Driver Model for PMIC PFUZE100" depends on DM_PMIC diff --git a/include/configs/apalis-tk1.h b/include/configs/apalis-tk1.h index a64037b5954..c6c956e1ee1 100644 --- a/include/configs/apalis-tk1.h +++ b/include/configs/apalis-tk1.h @@ -11,9 +11,6 @@ #include -/* enable PMIC */ -#define CONFIG_PMIC_AS3722 - #include "tegra124-common.h" #define CONFIG_ARCH_MISC_INIT diff --git a/include/configs/cei-tk1-som.h b/include/configs/cei-tk1-som.h index de56920fe99..8185926590e 100644 --- a/include/configs/cei-tk1-som.h +++ b/include/configs/cei-tk1-som.h @@ -14,9 +14,6 @@ #include -/* enable PMIC */ -#define CONFIG_PMIC_AS3722 - #include "tegra124-common.h" /* High-level configuration options */ diff --git a/include/configs/jetson-tk1.h b/include/configs/jetson-tk1.h index 5482f55ce0a..b31ba6a4ee5 100644 --- a/include/configs/jetson-tk1.h +++ b/include/configs/jetson-tk1.h @@ -10,9 +10,6 @@ #include -/* enable PMIC */ -#define CONFIG_PMIC_AS3722 - #include "tegra124-common.h" /* High-level configuration options */ diff --git a/include/configs/nyan-big.h b/include/configs/nyan-big.h index 906423dba94..a3a2a8cbcce 100644 --- a/include/configs/nyan-big.h +++ b/include/configs/nyan-big.h @@ -31,7 +31,6 @@ #define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) /* LCD support */ -#define CONFIG_PMIC_AS3722 #define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_CMD_BMP diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 1349fb0f7d8..f639d2b0824 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -2230,7 +2230,6 @@ CONFIG_PMECC_INDEX_TABLE_OFFSET CONFIG_PMECC_SECTOR_SIZE CONFIG_PME_PLAT_CLK_DIV CONFIG_PMIC -CONFIG_PMIC_AS3722 CONFIG_PMU CONFIG_PMW_BASE CONFIG_PM_SLEEP -- cgit v1.3.1 From 983b103f1cb1d2d6da039dbdcf1a85d3d2cc0cf4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 26 Apr 2017 22:27:57 -0600 Subject: Convert CONFIG_SYS_WHITE_ON_BLACK to Kconfig This converts the following to Kconfig: CONFIG_SYS_WHITE_ON_BLACK Signed-off-by: Simon Glass [trini: Make this default y on various SoCs] Signed-off-by: Tom Rini --- README | 3 --- configs/brppt1_mmc_defconfig | 1 + configs/brppt1_nand_defconfig | 1 + configs/brppt1_spi_defconfig | 1 + configs/brxre1_defconfig | 1 + configs/rpi_2_defconfig | 1 + configs/rpi_3_32b_defconfig | 1 + configs/rpi_3_defconfig | 1 + configs/rpi_defconfig | 1 + drivers/video/Kconfig | 9 +++++++++ include/configs/at91sam9261ek.h | 1 - include/configs/at91sam9263ek.h | 1 - include/configs/at91sam9m10g45ek.h | 1 - include/configs/at91sam9n12ek.h | 1 - include/configs/at91sam9rlek.h | 1 - include/configs/at91sam9x5ek.h | 1 - include/configs/brppt1.h | 1 - include/configs/brxre1.h | 1 - include/configs/colibri_pxa270.h | 1 - include/configs/colibri_t20.h | 1 - include/configs/evb_rk3288.h | 2 -- include/configs/evb_rk3328.h | 1 - include/configs/evb_rk3399.h | 2 -- include/configs/exynos5-dt-common.h | 1 - include/configs/fennec_rk3288.h | 2 -- include/configs/firefly-rk3288.h | 2 -- include/configs/harmony.h | 5 ----- include/configs/medcom-wide.h | 5 ----- include/configs/miqi_rk3288.h | 2 -- include/configs/nyan-big.h | 3 --- include/configs/paz00.h | 5 ----- include/configs/picosam9g45.h | 1 - include/configs/pm9261.h | 1 - include/configs/pm9263.h | 1 - include/configs/popmetal_rk3288.h | 2 -- include/configs/puma_rk3399.h | 2 -- include/configs/rock2.h | 2 -- include/configs/rpi.h | 1 - include/configs/s5pc210_universal.h | 1 - include/configs/sama5d2_xplained.h | 1 - include/configs/sama5d3xek.h | 1 - include/configs/sama5d4_xplained.h | 1 - include/configs/sama5d4ek.h | 1 - include/configs/seaboard.h | 7 ------- include/configs/tec.h | 5 ----- include/configs/tinker_rk3288.h | 2 -- include/configs/trats.h | 1 - include/configs/trats2.h | 1 - include/configs/ventana.h | 7 ------- include/configs/veyron.h | 2 -- include/configs/x86-chromebook.h | 2 -- scripts/config_whitelist.txt | 1 - 52 files changed, 17 insertions(+), 86 deletions(-) (limited to 'drivers') diff --git a/README b/README index 616dd5e348d..3afffbde1c5 100644 --- a/README +++ b/README @@ -1638,9 +1638,6 @@ The following options need to be configured: 320x240. Black & white. - Normally display is black on white background; define - CONFIG_SYS_WHITE_ON_BLACK to get it inverted. - CONFIG_LCD_ALIGNMENT Normally the LCD is page-aligned (typically 4KB). If this is diff --git a/configs/brppt1_mmc_defconfig b/configs/brppt1_mmc_defconfig index 621d7dbb433..7d92c139402 100644 --- a/configs/brppt1_mmc_defconfig +++ b/configs/brppt1_mmc_defconfig @@ -55,5 +55,6 @@ CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_USB_MUSB_HOST=y CONFIG_USB_STORAGE=y +CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_LCD=y CONFIG_OF_LIBFDT=y diff --git a/configs/brppt1_nand_defconfig b/configs/brppt1_nand_defconfig index a974e680a9e..9abe61760e1 100644 --- a/configs/brppt1_nand_defconfig +++ b/configs/brppt1_nand_defconfig @@ -55,5 +55,6 @@ CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_USB_MUSB_HOST=y CONFIG_USB_STORAGE=y +CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_LCD=y CONFIG_OF_LIBFDT=y diff --git a/configs/brppt1_spi_defconfig b/configs/brppt1_spi_defconfig index d1a786a90ff..79bb9057bfc 100644 --- a/configs/brppt1_spi_defconfig +++ b/configs/brppt1_spi_defconfig @@ -63,5 +63,6 @@ CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_USB_MUSB_HOST=y CONFIG_USB_STORAGE=y +CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_LCD=y CONFIG_OF_LIBFDT=y diff --git a/configs/brxre1_defconfig b/configs/brxre1_defconfig index 9616d9bc2c0..940793b5a67 100644 --- a/configs/brxre1_defconfig +++ b/configs/brxre1_defconfig @@ -55,6 +55,7 @@ CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_USB_MUSB_HOST=y CONFIG_USB_STORAGE=y +CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_LCD=y CONFIG_OF_LIBFDT=y # CONFIG_EFI_LOADER is not set diff --git a/configs/rpi_2_defconfig b/configs/rpi_2_defconfig index 9d669c92e42..9875f5d2950 100644 --- a/configs/rpi_2_defconfig +++ b/configs/rpi_2_defconfig @@ -19,6 +19,7 @@ CONFIG_MMC_SDHCI_BCM2835=y CONFIG_USB=y CONFIG_USB_STORAGE=y CONFIG_USB_KEYBOARD=y +CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_LCD=y CONFIG_PHYS_TO_BUS=y diff --git a/configs/rpi_3_32b_defconfig b/configs/rpi_3_32b_defconfig index d0f7beaa0b3..e4a81b882d1 100644 --- a/configs/rpi_3_32b_defconfig +++ b/configs/rpi_3_32b_defconfig @@ -21,6 +21,7 @@ CONFIG_MMC_SDHCI_BCM2835=y CONFIG_USB=y CONFIG_USB_STORAGE=y CONFIG_USB_KEYBOARD=y +CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_LCD=y CONFIG_PHYS_TO_BUS=y diff --git a/configs/rpi_3_defconfig b/configs/rpi_3_defconfig index ce28c312832..e0be6c76f8f 100644 --- a/configs/rpi_3_defconfig +++ b/configs/rpi_3_defconfig @@ -21,6 +21,7 @@ CONFIG_MMC_SDHCI_BCM2835=y CONFIG_USB=y CONFIG_USB_STORAGE=y CONFIG_USB_KEYBOARD=y +CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_LCD=y CONFIG_PHYS_TO_BUS=y diff --git a/configs/rpi_defconfig b/configs/rpi_defconfig index 4a90ca83486..a07d69800ce 100644 --- a/configs/rpi_defconfig +++ b/configs/rpi_defconfig @@ -19,6 +19,7 @@ CONFIG_MMC_SDHCI_BCM2835=y CONFIG_USB=y CONFIG_USB_STORAGE=y CONFIG_USB_KEYBOARD=y +CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_LCD=y CONFIG_PHYS_TO_BUS=y diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 19e97452bda..e29c3fcfc6d 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -89,6 +89,15 @@ config CONSOLE_TRUETYPE_SIZE method to select the display's physical size, which would allow U-Boot to calculate the correct font size. +config SYS_WHITE_ON_BLACK + bool "Display console as white on a black background" + default y if ARCH_AT91 || ARCH_EXYNOS || ARCH_ROCKCHIP || TEGRA || X86 + help + Normally the display is black on a white background, Enable this + option to invert this, i.e. white on a black background. This can be + better in low-light situations or to reduce eye strain in some + cases. + source "drivers/video/fonts/Kconfig" config VIDCONSOLE_AS_LCD diff --git a/include/configs/at91sam9261ek.h b/include/configs/at91sam9261ek.h index 0afc92c91de..505f945bd31 100644 --- a/include/configs/at91sam9261ek.h +++ b/include/configs/at91sam9261ek.h @@ -51,7 +51,6 @@ #undef LCD_TEST_PATTERN #define CONFIG_LCD_INFO #define CONFIG_LCD_INFO_BELOW_LOGO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_ATMEL_LCD #ifdef CONFIG_AT91SAM9261EK #define CONFIG_ATMEL_LCD_BGR555 diff --git a/include/configs/at91sam9263ek.h b/include/configs/at91sam9263ek.h index 51941312437..663c193a5b0 100644 --- a/include/configs/at91sam9263ek.h +++ b/include/configs/at91sam9263ek.h @@ -59,7 +59,6 @@ #undef LCD_TEST_PATTERN #define CONFIG_LCD_INFO 1 #define CONFIG_LCD_INFO_BELOW_LOGO 1 -#define CONFIG_SYS_WHITE_ON_BLACK 1 #define CONFIG_ATMEL_LCD 1 #define CONFIG_ATMEL_LCD_BGR555 1 diff --git a/include/configs/at91sam9m10g45ek.h b/include/configs/at91sam9m10g45ek.h index 0708d536623..a62b70b4596 100644 --- a/include/configs/at91sam9m10g45ek.h +++ b/include/configs/at91sam9m10g45ek.h @@ -44,7 +44,6 @@ #undef LCD_TEST_PATTERN #define CONFIG_LCD_INFO #define CONFIG_LCD_INFO_BELOW_LOGO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_ATMEL_LCD #define CONFIG_ATMEL_LCD_RGB565 /* board specific(not enough SRAM) */ diff --git a/include/configs/at91sam9n12ek.h b/include/configs/at91sam9n12ek.h index 872d471d055..dd49f4ebd3a 100644 --- a/include/configs/at91sam9n12ek.h +++ b/include/configs/at91sam9n12ek.h @@ -42,7 +42,6 @@ #define CONFIG_LCD_LOGO #define CONFIG_LCD_INFO #define CONFIG_LCD_INFO_BELOW_LOGO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_ATMEL_HLCD #define CONFIG_ATMEL_LCD_RGB565 diff --git a/include/configs/at91sam9rlek.h b/include/configs/at91sam9rlek.h index 8752f1f3b61..31a7cb18d86 100644 --- a/include/configs/at91sam9rlek.h +++ b/include/configs/at91sam9rlek.h @@ -47,7 +47,6 @@ #undef LCD_TEST_PATTERN #define CONFIG_LCD_INFO 1 #define CONFIG_LCD_INFO_BELOW_LOGO 1 -#define CONFIG_SYS_WHITE_ON_BLACK 1 #define CONFIG_ATMEL_LCD 1 #define CONFIG_ATMEL_LCD_RGB565 1 /* Let board_init_f handle the framebuffer allocation */ diff --git a/include/configs/at91sam9x5ek.h b/include/configs/at91sam9x5ek.h index c81003e3116..ff0a78ba437 100644 --- a/include/configs/at91sam9x5ek.h +++ b/include/configs/at91sam9x5ek.h @@ -39,7 +39,6 @@ #define CONFIG_LCD_LOGO #define CONFIG_LCD_INFO #define CONFIG_LCD_INFO_BELOW_LOGO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_ATMEL_HLCD #define CONFIG_ATMEL_LCD_RGB565 diff --git a/include/configs/brppt1.h b/include/configs/brppt1.h index 68e9efef1c2..0c1a54d7ba2 100644 --- a/include/configs/brppt1.h +++ b/include/configs/brppt1.h @@ -18,7 +18,6 @@ #define CONFIG_AM335X_LCD #define CONFIG_LCD_ROTATION #define CONFIG_LCD_DT_SIMPLEFB -#define CONFIG_SYS_WHITE_ON_BLACK #define LCD_BPP LCD_COLOR32 #define CONFIG_HW_WATCHDOG diff --git a/include/configs/brxre1.h b/include/configs/brxre1.h index 49aea8f1962..49f223a32aa 100644 --- a/include/configs/brxre1.h +++ b/include/configs/brxre1.h @@ -17,7 +17,6 @@ /* ------------------------------------------------------------------------- */ #define CONFIG_AM335X_LCD #define CONFIG_LCD_NOSTDOUT -#define CONFIG_SYS_WHITE_ON_BLACK #define LCD_BPP LCD_COLOR32 #define CONFIG_VIDEO_BMP_GZIP diff --git a/include/configs/colibri_pxa270.h b/include/configs/colibri_pxa270.h index 0dbd996920b..62a404a7b1d 100644 --- a/include/configs/colibri_pxa270.h +++ b/include/configs/colibri_pxa270.h @@ -65,7 +65,6 @@ #ifdef CONFIG_LCD #define CONFIG_PXA_LCD #define CONFIG_PXA_VGA -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_LCD_LOGO #endif diff --git a/include/configs/colibri_t20.h b/include/configs/colibri_t20.h index 743f92c9627..023e75cf33d 100644 --- a/include/configs/colibri_t20.h +++ b/include/configs/colibri_t20.h @@ -39,7 +39,6 @@ #define CONFIG_TFTP_TSIZE /* LCD support */ -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_LCD_LOGO /* NAND support */ diff --git a/include/configs/evb_rk3288.h b/include/configs/evb_rk3288.h index bbd54a1160f..0dc3532f330 100644 --- a/include/configs/evb_rk3288.h +++ b/include/configs/evb_rk3288.h @@ -13,6 +13,4 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 0 -#define CONFIG_SYS_WHITE_ON_BLACK - #endif diff --git a/include/configs/evb_rk3328.h b/include/configs/evb_rk3328.h index 3a39a1bffe5..fe3ec8c1778 100644 --- a/include/configs/evb_rk3328.h +++ b/include/configs/evb_rk3328.h @@ -20,7 +20,6 @@ #define SDRAM_BANK_SIZE (2UL << 30) -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_CONSOLE_SCROLL_LINES 10 #endif diff --git a/include/configs/evb_rk3399.h b/include/configs/evb_rk3399.h index 8fdefa29c72..b9fd5b417a7 100644 --- a/include/configs/evb_rk3399.h +++ b/include/configs/evb_rk3399.h @@ -20,6 +20,4 @@ #define SDRAM_BANK_SIZE (2UL << 30) -#define CONFIG_SYS_WHITE_ON_BLACK - #endif diff --git a/include/configs/exynos5-dt-common.h b/include/configs/exynos5-dt-common.h index 7cb3a296b57..1b94d07f674 100644 --- a/include/configs/exynos5-dt-common.h +++ b/include/configs/exynos5-dt-common.h @@ -31,7 +31,6 @@ #define CONFIG_EXYNOS_FB #define CONFIG_EXYNOS_DP #define LCD_BPP LCD_COLOR16 -#define CONFIG_SYS_WHITE_ON_BLACK #endif /* Enable keyboard */ diff --git a/include/configs/fennec_rk3288.h b/include/configs/fennec_rk3288.h index bbd54a1160f..0dc3532f330 100644 --- a/include/configs/fennec_rk3288.h +++ b/include/configs/fennec_rk3288.h @@ -13,6 +13,4 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 0 -#define CONFIG_SYS_WHITE_ON_BLACK - #endif diff --git a/include/configs/firefly-rk3288.h b/include/configs/firefly-rk3288.h index ec555dd9667..b4dcf23b1cf 100644 --- a/include/configs/firefly-rk3288.h +++ b/include/configs/firefly-rk3288.h @@ -17,6 +17,4 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 0 -#define CONFIG_SYS_WHITE_ON_BLACK - #endif diff --git a/include/configs/harmony.h b/include/configs/harmony.h index 923c38f9685..1a5d4b1dd5d 100644 --- a/include/configs/harmony.h +++ b/include/configs/harmony.h @@ -45,11 +45,6 @@ #define CONFIG_USB_ETHER_MCS7830 #define CONFIG_USB_ETHER_SMSC95XX -/* General networking support */ - -/* LCD support */ -#define CONFIG_SYS_WHITE_ON_BLACK - #include "tegra-common-post.h" #endif /* __CONFIG_H */ diff --git a/include/configs/medcom-wide.h b/include/configs/medcom-wide.h index 342bcf3051d..b9b666fd3e4 100644 --- a/include/configs/medcom-wide.h +++ b/include/configs/medcom-wide.h @@ -36,11 +36,6 @@ #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_SMSC95XX -/* General networking support */ - -/* LCD support */ -#define CONFIG_SYS_WHITE_ON_BLACK - #include "tegra-common-post.h" #endif /* __CONFIG_H */ diff --git a/include/configs/miqi_rk3288.h b/include/configs/miqi_rk3288.h index f6860424995..477f296542d 100644 --- a/include/configs/miqi_rk3288.h +++ b/include/configs/miqi_rk3288.h @@ -17,6 +17,4 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 0 -#define CONFIG_SYS_WHITE_ON_BLACK - #endif diff --git a/include/configs/nyan-big.h b/include/configs/nyan-big.h index 38bb6f343c6..d9d4f2d5837 100644 --- a/include/configs/nyan-big.h +++ b/include/configs/nyan-big.h @@ -30,9 +30,6 @@ #define CONFIG_SYS_MMC_ENV_PART 2 #define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) -/* LCD support */ -#define CONFIG_SYS_WHITE_ON_BLACK - /* Align LCD to 1MB boundary */ #define CONFIG_LCD_ALIGNMENT MMU_SECTION_SIZE diff --git a/include/configs/paz00.h b/include/configs/paz00.h index fe7be6983db..2e8cbd94cf6 100644 --- a/include/configs/paz00.h +++ b/include/configs/paz00.h @@ -36,11 +36,6 @@ #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_ASIX -/* General networking support */ - -/* LCD support */ -#define CONFIG_SYS_WHITE_ON_BLACK - #include "tegra-common-post.h" #endif /* __CONFIG_H */ diff --git a/include/configs/picosam9g45.h b/include/configs/picosam9g45.h index 61c4b98b1dc..733768aa7b2 100644 --- a/include/configs/picosam9g45.h +++ b/include/configs/picosam9g45.h @@ -47,7 +47,6 @@ #undef LCD_TEST_PATTERN #define CONFIG_LCD_INFO #define CONFIG_LCD_INFO_BELOW_LOGO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_ATMEL_LCD #define CONFIG_ATMEL_LCD_RGB565 /* board specific(not enough SRAM) */ diff --git a/include/configs/pm9261.h b/include/configs/pm9261.h index ca1404ae9fc..b22a3b6a2bf 100644 --- a/include/configs/pm9261.h +++ b/include/configs/pm9261.h @@ -152,7 +152,6 @@ #undef LCD_TEST_PATTERN #define CONFIG_LCD_INFO 1 #define CONFIG_LCD_INFO_BELOW_LOGO 1 -#define CONFIG_SYS_WHITE_ON_BLACK 1 #define CONFIG_ATMEL_LCD 1 #define CONFIG_ATMEL_LCD_BGR555 1 diff --git a/include/configs/pm9263.h b/include/configs/pm9263.h index 52791bce555..b220d14dd86 100644 --- a/include/configs/pm9263.h +++ b/include/configs/pm9263.h @@ -165,7 +165,6 @@ #undef LCD_TEST_PATTERN #define CONFIG_LCD_INFO 1 #define CONFIG_LCD_INFO_BELOW_LOGO 1 -#define CONFIG_SYS_WHITE_ON_BLACK 1 #define CONFIG_ATMEL_LCD 1 #define CONFIG_ATMEL_LCD_BGR555 1 diff --git a/include/configs/popmetal_rk3288.h b/include/configs/popmetal_rk3288.h index bbd54a1160f..0dc3532f330 100644 --- a/include/configs/popmetal_rk3288.h +++ b/include/configs/popmetal_rk3288.h @@ -13,6 +13,4 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 0 -#define CONFIG_SYS_WHITE_ON_BLACK - #endif diff --git a/include/configs/puma_rk3399.h b/include/configs/puma_rk3399.h index fd62c72a203..f7787443195 100644 --- a/include/configs/puma_rk3399.h +++ b/include/configs/puma_rk3399.h @@ -22,6 +22,4 @@ #define SDRAM_BANK_SIZE (2UL << 30) -#define CONFIG_SYS_WHITE_ON_BLACK - #endif diff --git a/include/configs/rock2.h b/include/configs/rock2.h index ec555dd9667..b4dcf23b1cf 100644 --- a/include/configs/rock2.h +++ b/include/configs/rock2.h @@ -17,6 +17,4 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 0 -#define CONFIG_SYS_WHITE_ON_BLACK - #endif diff --git a/include/configs/rpi.h b/include/configs/rpi.h index 244f5101974..5caf90a9ac2 100644 --- a/include/configs/rpi.h +++ b/include/configs/rpi.h @@ -76,7 +76,6 @@ */ #define CONFIG_FB_ADDR 0 #define CONFIG_VIDEO_BCM2835 -#define CONFIG_SYS_WHITE_ON_BLACK #ifdef CONFIG_CMD_USB #define CONFIG_USB_DWC2 diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h index 627a3411969..6c75626e824 100644 --- a/include/configs/s5pc210_universal.h +++ b/include/configs/s5pc210_universal.h @@ -190,7 +190,6 @@ int universal_spi_read(void); /* LCD console */ #define LCD_BPP LCD_COLOR16 -#define CONFIG_SYS_WHITE_ON_BLACK /* * LCD Settings diff --git a/include/configs/sama5d2_xplained.h b/include/configs/sama5d2_xplained.h index ccbcc765c3c..ea28fce6ef8 100644 --- a/include/configs/sama5d2_xplained.h +++ b/include/configs/sama5d2_xplained.h @@ -61,7 +61,6 @@ #define CONFIG_LCD_LOGO #define CONFIG_LCD_INFO #define CONFIG_LCD_INFO_BELOW_LOGO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_ATMEL_HLCD #define CONFIG_ATMEL_LCD_RGB565 #endif diff --git a/include/configs/sama5d3xek.h b/include/configs/sama5d3xek.h index 6c28c4c19eb..509457b9bf0 100644 --- a/include/configs/sama5d3xek.h +++ b/include/configs/sama5d3xek.h @@ -34,7 +34,6 @@ #define CONFIG_LCD_LOGO #define CONFIG_LCD_INFO #define CONFIG_LCD_INFO_BELOW_LOGO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_ATMEL_HLCD #define CONFIG_ATMEL_LCD_RGB565 diff --git a/include/configs/sama5d4_xplained.h b/include/configs/sama5d4_xplained.h index aced293fa84..c584b0b9e3f 100644 --- a/include/configs/sama5d4_xplained.h +++ b/include/configs/sama5d4_xplained.h @@ -54,7 +54,6 @@ #define CONFIG_LCD_LOGO #define CONFIG_LCD_INFO #define CONFIG_LCD_INFO_BELOW_LOGO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_ATMEL_HLCD #define CONFIG_ATMEL_LCD_RGB565 #endif diff --git a/include/configs/sama5d4ek.h b/include/configs/sama5d4ek.h index a5fd37f46b2..91f286b6477 100644 --- a/include/configs/sama5d4ek.h +++ b/include/configs/sama5d4ek.h @@ -53,7 +53,6 @@ #define CONFIG_LCD_LOGO #define CONFIG_LCD_INFO #define CONFIG_LCD_INFO_BELOW_LOGO -#define CONFIG_SYS_WHITE_ON_BLACK #define CONFIG_ATMEL_HLCD #define CONFIG_ATMEL_LCD_RGB565 diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h index 661d1fee6f8..207b59118d0 100644 --- a/include/configs/seaboard.h +++ b/include/configs/seaboard.h @@ -44,17 +44,10 @@ #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_ASIX -/* General networking support */ - /* Enable keyboard */ #define CONFIG_TEGRA_KEYBOARD #define CONFIG_KEYBOARD -/* USB keyboard */ - -/* LCD support */ -#define CONFIG_SYS_WHITE_ON_BLACK - /* NAND support */ #define CONFIG_CMD_NAND #define CONFIG_TEGRA_NAND diff --git a/include/configs/tec.h b/include/configs/tec.h index ebfca8f3199..b380a69bdf7 100644 --- a/include/configs/tec.h +++ b/include/configs/tec.h @@ -36,11 +36,6 @@ #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_SMSC95XX -/* General networking support */ - -/* LCD support */ -#define CONFIG_SYS_WHITE_ON_BLACK - #include "tegra-common-post.h" #endif /* __CONFIG_H */ diff --git a/include/configs/tinker_rk3288.h b/include/configs/tinker_rk3288.h index 402ae2def22..72578f9202b 100644 --- a/include/configs/tinker_rk3288.h +++ b/include/configs/tinker_rk3288.h @@ -21,6 +21,4 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 1 -#define CONFIG_SYS_WHITE_ON_BLACK - #endif diff --git a/include/configs/trats.h b/include/configs/trats.h index 1e68c032428..6806cd95650 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -202,7 +202,6 @@ /* LCD console */ #define LCD_BPP LCD_COLOR16 -#define CONFIG_SYS_WHITE_ON_BLACK /* LCD */ #define CONFIG_BMP_16BPP diff --git a/include/configs/trats2.h b/include/configs/trats2.h index 722d492518f..6a4604ce938 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -183,7 +183,6 @@ /* LCD console */ #define LCD_BPP LCD_COLOR16 -#define CONFIG_SYS_WHITE_ON_BLACK /* LCD */ #define CONFIG_BMP_16BPP diff --git a/include/configs/ventana.h b/include/configs/ventana.h index 87b5136facb..0e851a1b108 100644 --- a/include/configs/ventana.h +++ b/include/configs/ventana.h @@ -34,13 +34,6 @@ #define CONFIG_USB_HOST_ETHER #define CONFIG_USB_ETHER_ASIX -/* General networking support */ - -/* USB keyboard */ - -/* LCD support */ -#define CONFIG_SYS_WHITE_ON_BLACK - #include "tegra-common-post.h" #endif /* __CONFIG_H */ diff --git a/include/configs/veyron.h b/include/configs/veyron.h index b15cc26bebc..3bd8dd60b5b 100644 --- a/include/configs/veyron.h +++ b/include/configs/veyron.h @@ -22,6 +22,4 @@ #define CONFIG_KEYBOARD -#define CONFIG_SYS_WHITE_ON_BLACK - #endif diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h index e8ad29d3d09..b0e7e8115f7 100644 --- a/include/configs/x86-chromebook.h +++ b/include/configs/x86-chromebook.h @@ -46,8 +46,6 @@ #define CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_OFFSET 0x003f8000 -#define CONFIG_SYS_WHITE_ON_BLACK - #define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,i8042-kbd,serial\0" \ "stdout=vidconsole,serial\0" \ "stderr=vidconsole,serial\0" diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index df115d1106c..58e1522e6f4 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -6229,7 +6229,6 @@ CONFIG_SYS_WDTC_WDMR_VAL CONFIG_SYS_WDTTIMERBASE CONFIG_SYS_WDT_PERIOD_HIGH CONFIG_SYS_WDT_PERIOD_LOW -CONFIG_SYS_WHITE_ON_BLACK CONFIG_SYS_WINDOW1_BASE CONFIG_SYS_WRITE_SWAPPED_DATA CONFIG_SYS_XHCI_USB1_ADDR -- cgit v1.3.1 From ae189ba1ac85e47fe57d6422bc9474ff081a30a4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 26 Apr 2017 22:28:11 -0600 Subject: Drop the pdsp188x driver This is not used in U-Boot. Signed-off-by: Simon Glass --- drivers/misc/Makefile | 1 - drivers/misc/pdsp188x.c | 45 -------------------------------------------- scripts/config_whitelist.txt | 1 - 3 files changed, 47 deletions(-) delete mode 100644 drivers/misc/pdsp188x.c (limited to 'drivers') diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index e3151ea097c..4543cd647e5 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o obj-$(CONFIG_NS87308) += ns87308.o -obj-$(CONFIG_PDSP188x) += pdsp188x.o obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o ifdef CONFIG_DM_I2C ifndef CONFIG_SPL_BUILD diff --git a/drivers/misc/pdsp188x.c b/drivers/misc/pdsp188x.c deleted file mode 100644 index aa4351a0ad4..00000000000 --- a/drivers/misc/pdsp188x.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2010 Sergey Poselenov, Emcraft Systems, - * Copyright 2010 Ilya Yanok, Emcraft Systems, - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#ifdef CONFIG_CMD_DISPLAY -#define CWORD_CLEAR 0x80 -#define CLEAR_DELAY (110 * 2) -#define DISPLAY_SIZE 8 - -static int pos; /* Current display position */ - -/* Handle different display commands */ -void display_set(int cmd) -{ - if (cmd & DISPLAY_CLEAR) { - out_8((unsigned char *)CONFIG_SYS_DISP_CWORD, CWORD_CLEAR); - udelay(1000 * CLEAR_DELAY); - } - - if (cmd & DISPLAY_HOME) { - pos = 0; - } -} - -/* - * Display a character at the current display position. - * Characters beyond the display size are ignored. - */ -int display_putc(char c) -{ - if (pos >= DISPLAY_SIZE) - return -1; - - out_8((unsigned char *)CONFIG_SYS_DISP_CHR_RAM + pos++, c); - - return c; -} -#endif diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 11689e85808..5cd7103c0d6 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -2137,7 +2137,6 @@ CONFIG_PCNET CONFIG_PCNET_79C973 CONFIG_PCNET_79C975 CONFIG_PDM360NG -CONFIG_PDSP188x CONFIG_PEN_ADDR_BIG_ENDIAN CONFIG_PERIF1_FREQ CONFIG_PERIF2_FREQ -- cgit v1.3.1 From 61a77ce1d5a63856328605822b69d8abaeb7f593 Mon Sep 17 00:00:00 2001 From: Wenyou Yang Date: Fri, 7 Apr 2017 15:14:46 +0800 Subject: spi: atmel: check GPIO validity before using cs_gpios Before using the cs_gpio, check if the GPIO is valid or not. Signed-off-by: Wenyou Yang Reviewed-by: Jagan Teki --- drivers/spi/atmel_spi.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 76491142318..4701b79f161 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -296,6 +296,9 @@ static void atmel_spi_cs_activate(struct udevice *dev) struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); u32 cs = slave_plat->cs; + if (!dm_gpio_is_valid(&priv->cs_gpios[cs])) + return; + dm_gpio_set_value(&priv->cs_gpios[cs], 0); } @@ -306,6 +309,9 @@ static void atmel_spi_cs_deactivate(struct udevice *dev) struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); u32 cs = slave_plat->cs; + if (!dm_gpio_is_valid(&priv->cs_gpios[cs])) + return; + dm_gpio_set_value(&priv->cs_gpios[cs], 1); } @@ -473,6 +479,9 @@ static int atmel_spi_probe(struct udevice *bus) } for(i = 0; i < ARRAY_SIZE(priv->cs_gpios); i++) { + if (!dm_gpio_is_valid(&priv->cs_gpios[i])) + continue; + dm_gpio_set_dir_flags(&priv->cs_gpios[i], GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); } -- cgit v1.3.1 From ac6991fb5fc1a694b29f4ebd5e07baebf818d7cc Mon Sep 17 00:00:00 2001 From: Moritz Fischer Date: Thu, 8 Dec 2016 12:11:09 -0800 Subject: zynq: spi: Honour the activation / deactivation delay This is not currently implemented. Add support for this so that the Chrome OS EC can be used reliably. Signed-off-by: Moritz Fischer Acked-by: Simon Glass Reviewed-by: Jagan Teki --- drivers/spi/zynq_spi.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c index 5a9b1f0f2ee..2b77f1ccdcf 100644 --- a/drivers/spi/zynq_spi.c +++ b/drivers/spi/zynq_spi.c @@ -56,6 +56,8 @@ struct zynq_spi_platdata { struct zynq_spi_regs *regs; u32 frequency; /* input frequency */ u32 speed_hz; + uint deactivate_delay_us; /* Delay to wait after deactivate */ + uint activate_delay_us; /* Delay to wait after activate */ }; /* zynq spi priv */ @@ -63,6 +65,7 @@ struct zynq_spi_priv { struct zynq_spi_regs *regs; u8 cs; u8 mode; + ulong last_transaction_us; /* Time of last transaction end */ u8 fifo_depth; u32 freq; /* required frequency */ }; @@ -78,6 +81,10 @@ static int zynq_spi_ofdata_to_platdata(struct udevice *bus) /* FIXME: Use 250MHz as a suitable default */ plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", 250000000); + plat->deactivate_delay_us = fdtdec_get_int(blob, node, + "spi-deactivate-delay", 0); + plat->activate_delay_us = fdtdec_get_int(blob, node, + "spi-activate-delay", 0); plat->speed_hz = plat->frequency / 2; debug("%s: regs=%p max-frequency=%d\n", __func__, @@ -133,10 +140,19 @@ static int zynq_spi_probe(struct udevice *bus) static void spi_cs_activate(struct udevice *dev) { struct udevice *bus = dev->parent; + struct zynq_spi_platdata *plat = bus->platdata; struct zynq_spi_priv *priv = dev_get_priv(bus); struct zynq_spi_regs *regs = priv->regs; u32 cr; + /* If it's too soon to do another transaction, wait */ + if (plat->deactivate_delay_us && priv->last_transaction_us) { + ulong delay_us; /* The delay completed so far */ + delay_us = timer_get_us() - priv->last_transaction_us; + if (delay_us < plat->deactivate_delay_us) + udelay(plat->deactivate_delay_us - delay_us); + } + clrbits_le32(®s->cr, ZYNQ_SPI_CR_CS_MASK); cr = readl(®s->cr); /* @@ -147,15 +163,23 @@ static void spi_cs_activate(struct udevice *dev) */ cr |= (~(1 << priv->cs) << ZYNQ_SPI_CR_SS_SHIFT) & ZYNQ_SPI_CR_CS_MASK; writel(cr, ®s->cr); + + if (plat->activate_delay_us) + udelay(plat->activate_delay_us); } static void spi_cs_deactivate(struct udevice *dev) { struct udevice *bus = dev->parent; + struct zynq_spi_platdata *plat = bus->platdata; struct zynq_spi_priv *priv = dev_get_priv(bus); struct zynq_spi_regs *regs = priv->regs; setbits_le32(®s->cr, ZYNQ_SPI_CR_CS_MASK); + + /* Remember time of this transaction so we can honour the bus delay */ + if (plat->deactivate_delay_us) + priv->last_transaction_us = timer_get_us(); } static int zynq_spi_claim_bus(struct udevice *dev) -- cgit v1.3.1 From 2f54205829429d82c7591340a106bf68f3916120 Mon Sep 17 00:00:00 2001 From: Suniel Mahesh Date: Wed, 3 May 2017 11:47:29 +0530 Subject: drivers: spi: Remove duplicate .probe method .probe method has been assigned twice when declaring a driver with U_BOOT_DRIVER(). Removed one of them. Here is the last commit which had the duplicate entry: "spi: omap3: Convert to driver model" (sha1: 77b8d04854f486741471ad02b93b473b5b3d72f8) Signed-off-by: Suniel Mahesh Reviewed-by: Jagan Teki --- drivers/spi/omap3_spi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c index 8a894501097..76d376ac445 100644 --- a/drivers/spi/omap3_spi.c +++ b/drivers/spi/omap3_spi.c @@ -692,6 +692,5 @@ U_BOOT_DRIVER(omap3_spi) = { .probe = omap3_spi_probe, .ops = &omap3_spi_ops, .priv_auto_alloc_size = sizeof(struct omap3_spi_priv), - .probe = omap3_spi_probe, }; #endif -- cgit v1.3.1 From ef3f3b8100b28f2110c8a5f5181a5d6ee5db9160 Mon Sep 17 00:00:00 2001 From: Uri Mashiach Date: Thu, 23 Feb 2017 15:39:36 +0200 Subject: arm: usb: dra7xx: xHCI registers based on USB port index Modify the determination of the base address of xHCI registers of DRA7XX targets. Before the commit: by the target. After the commit: by the USB port index. Cc: Lokesh Vutla Cc: Marek Vasut Cc: Roger Quadros Signed-off-by: Uri Mashiach Reviewed-by: Marek Vasut Reviewed-by: Tom Rini Reviewed-by: Roger Quadros Acked-by: Marek Vasut Acked-by: Marek Vasut --- configs/dra7xx_evm_defconfig | 1 + configs/dra7xx_hs_evm_defconfig | 1 + drivers/usb/host/Kconfig | 9 +++++++++ include/linux/usb/xhci-omap.h | 6 ++++-- 4 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig index 462e6ff4082..b52885c12a6 100644 --- a/configs/dra7xx_evm_defconfig +++ b/configs/dra7xx_evm_defconfig @@ -91,6 +91,7 @@ CONFIG_OMAP_TIMER=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_XHCI_DRA7XX_INDEX=1 CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_OMAP=y diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig index a348878342b..885ecae637d 100644 --- a/configs/dra7xx_hs_evm_defconfig +++ b/configs/dra7xx_hs_evm_defconfig @@ -96,6 +96,7 @@ CONFIG_OMAP_TIMER=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_XHCI_DRA7XX_INDEX=1 CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_OMAP=y diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 0bf8274405f..fb5aa6f8891 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -44,6 +44,15 @@ config USB_XHCI_ZYNQMP help Enables support for the on-chip xHCI controller on Xilinx ZynqMP SoCs. +config USB_XHCI_DRA7XX_INDEX + int "DRA7XX xHCI USB index" + range 0 1 + default 0 + depends on DRA7XX + help + Select the DRA7XX xHCI USB index. + Current supported values: 0, 1. + endif # USB_XHCI_HCD config USB_EHCI_HCD diff --git a/include/linux/usb/xhci-omap.h b/include/linux/usb/xhci-omap.h index 9de80d738ec..f038ddb6693 100644 --- a/include/linux/usb/xhci-omap.h +++ b/include/linux/usb/xhci-omap.h @@ -10,14 +10,16 @@ #ifndef _ASM_ARCH_XHCI_OMAP_H_ #define _ASM_ARCH_XHCI_OMAP_H_ -#ifdef CONFIG_TARGET_DRA7XX_EVM +#ifdef CONFIG_DRA7XX +#if CONFIG_USB_XHCI_DRA7XX_INDEX == 1 #define OMAP_XHCI_BASE 0x488d0000 #define OMAP_OCP1_SCP_BASE 0x4A081000 #define OMAP_OTG_WRAPPER_BASE 0x488c0000 -#elif defined CONFIG_TARGET_AM57XX_EVM +#elif CONFIG_USB_XHCI_DRA7XX_INDEX == 0 #define OMAP_XHCI_BASE 0x48890000 #define OMAP_OCP1_SCP_BASE 0x4A084c00 #define OMAP_OTG_WRAPPER_BASE 0x48880000 +#endif /* CONFIG_USB_XHCI_DRA7XX_INDEX == 1 */ #elif defined CONFIG_AM43XX #define OMAP_XHCI_BASE 0x483d0000 #define OMAP_OCP1_SCP_BASE 0x483E8000 -- cgit v1.3.1 From 1a9a5f7a39d655868d7e51327786ca6bccbbec68 Mon Sep 17 00:00:00 2001 From: Uri Mashiach Date: Thu, 23 Feb 2017 15:39:37 +0200 Subject: usb: host: xhci-omap: fix double weak board_usb_init functions A weak version of the function board_usb_init is implemented in: common/usb.c drivers/usb/host/xhci-omap.c To fix the double implementations: * Convert the board_usb_init function in drivers/usb/host/xhci-omap.c normal (not weak). * The function board_usb_init in drivers/usb/host/xhci-omap.c calls to the weak function omap_xhci_board_usb_init. * Rename board version of the function board_usb_init to omap_xhci_board_usb_init. Done only for boards that defines CONFIG_USB_XHCI_OMAP. To achieve the same flexibility with the function board_usb_cleanup: * Add a normal (not weak) implementation of the function board_usb_cleanup in drivers/usb/host/xhci-omap.c * The function board_usb_cleanup in drivers/usb/host/xhci-omap.c calls to the weak function omap_xhci_board_usb_cleanup. * Rename board version of the function board_usb_cleanup to omap_xhci_board_usb_cleanup. Done only for boards that defines CONFIG_USB_XHCI_OMAP. Cc: Lokesh Vutla Signed-off-by: Uri Mashiach Acked-by: Marek Vasut Reviewed-by: Tom Rini Reviewed-by: Roger Quadros --- board/compulab/cl-som-am57x/cl-som-am57x.c | 2 +- board/ti/am43xx/board.c | 4 ++-- board/ti/am57xx/board.c | 4 ++-- board/ti/dra7xx/evm.c | 4 ++-- drivers/usb/host/xhci-omap.c | 17 +++++++++++++++-- 5 files changed, 22 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/board/compulab/cl-som-am57x/cl-som-am57x.c b/board/compulab/cl-som-am57x/cl-som-am57x.c index bdd0a2ba198..fe1468f80b9 100644 --- a/board/compulab/cl-som-am57x/cl-som-am57x.c +++ b/board/compulab/cl-som-am57x/cl-som-am57x.c @@ -54,7 +54,7 @@ int board_mmc_init(bd_t *bis) #endif /* CONFIG_GENERIC_MMC */ #ifdef CONFIG_USB_XHCI_OMAP -int board_usb_init(int index, enum usb_init_type init) +int omap_xhci_board_usb_init(int index, enum usb_init_type init) { setbits_le32((*prcm)->cm_l3init_usb_otg_ss1_clkctrl, OTG_SS_CLKCTRL_MODULEMODE_HW | OPTFCLKEN_REFCLK960M); diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c index 390cc168cda..2572029a256 100644 --- a/board/ti/am43xx/board.c +++ b/board/ti/am43xx/board.c @@ -694,7 +694,7 @@ int usb_gadget_handle_interrupts(int index) #endif /* CONFIG_USB_DWC3 */ #if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) -int board_usb_init(int index, enum usb_init_type init) +int omap_xhci_board_usb_init(int index, enum usb_init_type init) { enable_usb_clocks(index); #ifdef CONFIG_USB_DWC3 @@ -725,7 +725,7 @@ int board_usb_init(int index, enum usb_init_type init) return 0; } -int board_usb_cleanup(int index, enum usb_init_type init) +int omap_xhci_board_usb_cleanup(int index, enum usb_init_type init) { #ifdef CONFIG_USB_DWC3 switch (index) { diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c index 1cfc08bc9ce..6d444e09faf 100644 --- a/board/ti/am57xx/board.c +++ b/board/ti/am57xx/board.c @@ -720,7 +720,7 @@ int usb_gadget_handle_interrupts(int index) #endif /* CONFIG_USB_DWC3 */ #if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) -int board_usb_init(int index, enum usb_init_type init) +int omap_xhci_board_usb_init(int index, enum usb_init_type init) { enable_usb_clocks(index); switch (index) { @@ -754,7 +754,7 @@ int board_usb_init(int index, enum usb_init_type init) return 0; } -int board_usb_cleanup(int index, enum usb_init_type init) +int omap_xhci_board_usb_cleanup(int index, enum usb_init_type init) { #ifdef CONFIG_USB_DWC3 switch (index) { diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c index ed0bc181cf5..d8e48dd3f82 100644 --- a/board/ti/dra7xx/evm.c +++ b/board/ti/dra7xx/evm.c @@ -750,7 +750,7 @@ static struct ti_usb_phy_device usb_phy2_device = { .index = 1, }; -int board_usb_init(int index, enum usb_init_type init) +int omap_xhci_board_usb_init(int index, enum usb_init_type init) { enable_usb_clocks(index); switch (index) { @@ -787,7 +787,7 @@ int board_usb_init(int index, enum usb_init_type init) return 0; } -int board_usb_cleanup(int index, enum usb_init_type init) +int omap_xhci_board_usb_cleanup(int index, enum usb_init_type init) { switch (index) { case 0: diff --git a/drivers/usb/host/xhci-omap.c b/drivers/usb/host/xhci-omap.c index b881b198fc8..a1b4f2f05cc 100644 --- a/drivers/usb/host/xhci-omap.c +++ b/drivers/usb/host/xhci-omap.c @@ -27,12 +27,25 @@ DECLARE_GLOBAL_DATA_PTR; static struct omap_xhci omap; -__weak int __board_usb_init(int index, enum usb_init_type init) +__weak int omap_xhci_board_usb_init(int index, enum usb_init_type init) { return 0; } + int board_usb_init(int index, enum usb_init_type init) - __attribute__((weak, alias("__board_usb_init"))); +{ + return omap_xhci_board_usb_init(index, init); +} + +__weak int omap_xhci_board_usb_cleanup(int index, enum usb_init_type init) +{ + return 0; +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + return omap_xhci_board_usb_cleanup(index, init); +} static int omap_xhci_core_init(struct omap_xhci *omap) { -- cgit v1.3.1 From 4acfe1ae46ca7731544dda57ce42d10acc2d63c5 Mon Sep 17 00:00:00 2001 From: Uri Mashiach Date: Thu, 23 Feb 2017 15:39:38 +0200 Subject: arm: am57xx: cl-som-am57x: invoke clock API to enable/disable clocks Invoke enable_usb_clocks during board_usb_init and disable_usb_clocks during board_usb_exit to enable and disable clocks respectively. Modifications: * Enable USB clocks in the OMAP version of the function board_usb_init. * Disable USB clocks in the OMAP version of the function board_usb_cleanup. Cc: Marek Vasut Signed-off-by: Uri Mashiach Reviewed-by: Marek Vasut Reviewed-by: Tom Rini --- board/compulab/cl-som-am57x/cl-som-am57x.c | 10 ---------- drivers/usb/host/xhci-omap.c | 2 ++ 2 files changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/board/compulab/cl-som-am57x/cl-som-am57x.c b/board/compulab/cl-som-am57x/cl-som-am57x.c index fe1468f80b9..4701b711025 100644 --- a/board/compulab/cl-som-am57x/cl-som-am57x.c +++ b/board/compulab/cl-som-am57x/cl-som-am57x.c @@ -53,16 +53,6 @@ int board_mmc_init(bd_t *bis) } #endif /* CONFIG_GENERIC_MMC */ -#ifdef CONFIG_USB_XHCI_OMAP -int omap_xhci_board_usb_init(int index, enum usb_init_type init) -{ - setbits_le32((*prcm)->cm_l3init_usb_otg_ss1_clkctrl, - OTG_SS_CLKCTRL_MODULEMODE_HW | OPTFCLKEN_REFCLK960M); - - return 0; -} -#endif /* CONFIG_USB_XHCI_OMAP */ - int misc_init_r(void) { cl_print_pcb_info(); diff --git a/drivers/usb/host/xhci-omap.c b/drivers/usb/host/xhci-omap.c index a1b4f2f05cc..d6c57448184 100644 --- a/drivers/usb/host/xhci-omap.c +++ b/drivers/usb/host/xhci-omap.c @@ -29,6 +29,7 @@ static struct omap_xhci omap; __weak int omap_xhci_board_usb_init(int index, enum usb_init_type init) { + enable_usb_clocks(index); return 0; } @@ -39,6 +40,7 @@ int board_usb_init(int index, enum usb_init_type init) __weak int omap_xhci_board_usb_cleanup(int index, enum usb_init_type init) { + disable_usb_clocks(index); return 0; } -- cgit v1.3.1 From 890bafd752460b79c607e829f58bf88f0f8484b7 Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Mon, 10 Apr 2017 15:02:50 -0700 Subject: stm32f7: use clock driver to enable qspi controller clock Signed-off-by: Vikas Manocha cc: Christophe KERELLO --- arch/arm/dts/stm32f746.dtsi | 1 + drivers/spi/stm32_qspi.c | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi index b2b0b5f0992..883f818578c 100644 --- a/arch/arm/dts/stm32f746.dtsi +++ b/arch/arm/dts/stm32f746.dtsi @@ -78,6 +78,7 @@ reg-names = "QuadSPI", "QuadSPI-memory"; interrupts = <92>; spi-max-frequency = <108000000>; + clocks = <&rcc 0 65>; status = "disabled"; }; usart1: serial@40011000 { diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c index 05358ebf4cd..f0434a4413d 100644 --- a/drivers/spi/stm32_qspi.c +++ b/drivers/spi/stm32_qspi.c @@ -17,6 +17,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -457,7 +458,20 @@ static int stm32_qspi_probe(struct udevice *bus) priv->max_hz = plat->max_hz; - clock_setup(QSPI_CLOCK_CFG); +#ifdef CONFIG_CLK + int ret; + struct clk clk; + ret = clk_get_by_index(bus, 0, &clk); + if (ret < 0) + return ret; + + ret = clk_enable(&clk); + + if (ret) { + dev_err(bus, "failed to enable clock\n"); + return ret; + } +#endif setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT); -- cgit v1.3.1 From bf1ae4426b89bd8b3e036e012acc4bc88fec4c6e Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Mon, 10 Apr 2017 15:02:51 -0700 Subject: stm32f7: sdram: move sdram driver code to ram drivers area Signed-off-by: Vikas Manocha cc: Christophe KERELLO --- board/st/stm32f746-disco/stm32f746-disco.c | 113 +-------------------------- configs/stm32f746-disco_defconfig | 6 ++ drivers/ram/Kconfig | 8 ++ drivers/ram/Makefile | 1 + drivers/ram/stm32_sdram.c | 119 +++++++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 112 deletions(-) create mode 100644 drivers/ram/stm32_sdram.c (limited to 'drivers') diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c index fdad8d13a7c..15693588137 100644 --- a/board/st/stm32f746-disco/stm32f746-disco.c +++ b/board/st/stm32f746-disco/stm32f746-disco.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -106,57 +105,8 @@ out: return rv; } -static inline u32 _ns2clk(u32 ns, u32 freq) -{ - u32 tmp = freq/1000000; - return (tmp * ns) / 1000; -} - -#define NS2CLK(ns) (_ns2clk(ns, freq)) - -/* - * Following are timings for IS42S16400J, from corresponding datasheet - */ -#define SDRAM_CAS 3 /* 3 cycles */ -#define SDRAM_NB 1 /* Number of banks */ -#define SDRAM_MWID 1 /* 16 bit memory */ - -#define SDRAM_NR 0x1 /* 12-bit row */ -#define SDRAM_NC 0x0 /* 8-bit col */ -#define SDRAM_RBURST 0x1 /* Single read requests always as bursts */ -#define SDRAM_RPIPE 0x0 /* No HCLK clock cycle delay */ - -#define SDRAM_TRRD NS2CLK(12) -#define SDRAM_TRCD NS2CLK(18) -#define SDRAM_TRP NS2CLK(18) -#define SDRAM_TRAS NS2CLK(42) -#define SDRAM_TRC NS2CLK(60) -#define SDRAM_TRFC NS2CLK(60) -#define SDRAM_TCDL (1 - 1) -#define SDRAM_TRDL NS2CLK(12) -#define SDRAM_TBDL (1 - 1) -#define SDRAM_TREF (NS2CLK(64000000 / 8192) - 20) -#define SDRAM_TCCD (1 - 1) - -#define SDRAM_TXSR SDRAM_TRFC /* Row cycle time after precharge */ -#define SDRAM_TMRD 1 /* Page 10, Mode Register Set */ - - -/* Last data in to row precharge, need also comply ineq on page 1648 */ -#define SDRAM_TWR max(\ - (int)max((int)SDRAM_TRDL, (int)(SDRAM_TRAS - SDRAM_TRCD)), \ - (int)(SDRAM_TRC - SDRAM_TRCD - SDRAM_TRP)\ -) - - -#define SDRAM_MODE_BL_SHIFT 0 -#define SDRAM_MODE_CAS_SHIFT 4 -#define SDRAM_MODE_BL 0 -#define SDRAM_MODE_CAS SDRAM_CAS - int dram_init(void) { - u32 freq; int rv; rv = fmc_setup_gpio(); @@ -164,67 +114,7 @@ int dram_init(void) return rv; clock_setup(FMC_CLOCK_CFG); - - /* - * Get frequency for NS2CLK calculation. - */ - freq = clock_get(CLOCK_AHB) / CONFIG_SYS_RAM_FREQ_DIV; - - writel( - CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT - | SDRAM_CAS << FMC_SDCR_CAS_SHIFT - | SDRAM_NB << FMC_SDCR_NB_SHIFT - | SDRAM_MWID << FMC_SDCR_MWID_SHIFT - | SDRAM_NR << FMC_SDCR_NR_SHIFT - | SDRAM_NC << FMC_SDCR_NC_SHIFT - | SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT - | SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT, - &STM32_SDRAM_FMC->sdcr1); - - writel( - SDRAM_TRCD << FMC_SDTR_TRCD_SHIFT - | SDRAM_TRP << FMC_SDTR_TRP_SHIFT - | SDRAM_TWR << FMC_SDTR_TWR_SHIFT - | SDRAM_TRC << FMC_SDTR_TRC_SHIFT - | SDRAM_TRAS << FMC_SDTR_TRAS_SHIFT - | SDRAM_TXSR << FMC_SDTR_TXSR_SHIFT - | SDRAM_TMRD << FMC_SDTR_TMRD_SHIFT, - &STM32_SDRAM_FMC->sdtr1); - - writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK, - &STM32_SDRAM_FMC->sdcmr); - - udelay(200); /* 200 us delay, page 10, "Power-Up" */ - FMC_BUSY_WAIT(); - - writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_PRECHARGE, - &STM32_SDRAM_FMC->sdcmr); - - udelay(100); - FMC_BUSY_WAIT(); - - writel((FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_AUTOREFRESH - | 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr); - - udelay(100); - FMC_BUSY_WAIT(); - - writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT - | SDRAM_MODE_CAS << SDRAM_MODE_CAS_SHIFT) - << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE, - &STM32_SDRAM_FMC->sdcmr); - - udelay(100); - - FMC_BUSY_WAIT(); - - writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_NORMAL, - &STM32_SDRAM_FMC->sdcmr); - - FMC_BUSY_WAIT(); - - /* Refresh timer */ - writel(SDRAM_TREF, &STM32_SDRAM_FMC->sdrtr); + stm32_sdram_init(); /* * Fill in global info with description of SRAM configuration @@ -233,7 +123,6 @@ int dram_init(void) gd->bd->bi_dram[0].size = CONFIG_SYS_RAM_SIZE; gd->ram_size = CONFIG_SYS_RAM_SIZE; - return rv; } diff --git a/configs/stm32f746-disco_defconfig b/configs/stm32f746-disco_defconfig index ea98391684b..57a0d610df3 100644 --- a/configs/stm32f746-disco_defconfig +++ b/configs/stm32f746-disco_defconfig @@ -43,3 +43,9 @@ CONFIG_DM_SPI=y CONFIG_STM32_QSPI=y CONFIG_OF_LIBFDT_OVERLAY=y # CONFIG_EFI_LOADER is not set +CONFIG_CLK=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_FULL is not set +CONFIG_PINCTRL_STM32=y +CONFIG_RAM=y +CONFIG_STM32_SDRAM=y diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig index ff09f226dfd..61afd7a92a4 100644 --- a/drivers/ram/Kconfig +++ b/drivers/ram/Kconfig @@ -16,3 +16,11 @@ config SPL_RAM If this is acceptable and you have a need to use RAM drivers in SPL, enable this option. It might provide a cleaner interface to setting up RAM (e.g. SDRAM / DDR) within SPL. + +config STM32_SDRAM + bool "Enable STM32 SDRAM support" + depends on RAM + help + STM32F7 family devices support flexible memory controller(FMC) to + support external memories like sdram, psram & nand. + This driver is for the sdram memory interface with the FMC. diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile index 0e102491a4a..ecb036dfbab 100644 --- a/drivers/ram/Makefile +++ b/drivers/ram/Makefile @@ -6,3 +6,4 @@ # obj-$(CONFIG_RAM) += ram-uclass.o obj-$(CONFIG_SANDBOX) += sandbox_ram.o +obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c new file mode 100644 index 00000000000..13f896484e6 --- /dev/null +++ b/drivers/ram/stm32_sdram.c @@ -0,0 +1,119 @@ +/* + * (C) Copyright 2017 + * Vikas Manocha, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static inline u32 _ns2clk(u32 ns, u32 freq) +{ + u32 tmp = freq/1000000; + return (tmp * ns) / 1000; +} + +#define NS2CLK(ns) (_ns2clk(ns, freq)) + +/* + * Following are timings for IS42S16400J, from corresponding datasheet + */ +#define SDRAM_CAS 3 /* 3 cycles */ +#define SDRAM_NB 1 /* Number of banks */ +#define SDRAM_MWID 1 /* 16 bit memory */ + +#define SDRAM_NR 0x1 /* 12-bit row */ +#define SDRAM_NC 0x0 /* 8-bit col */ +#define SDRAM_RBURST 0x1 /* Single read requests always as bursts */ +#define SDRAM_RPIPE 0x0 /* No HCLK clock cycle delay */ + +#define SDRAM_TRRD NS2CLK(12) +#define SDRAM_TRCD NS2CLK(18) +#define SDRAM_TRP NS2CLK(18) +#define SDRAM_TRAS NS2CLK(42) +#define SDRAM_TRC NS2CLK(60) +#define SDRAM_TRFC NS2CLK(60) +#define SDRAM_TCDL (1 - 1) +#define SDRAM_TRDL NS2CLK(12) +#define SDRAM_TBDL (1 - 1) +#define SDRAM_TREF (NS2CLK(64000000 / 8192) - 20) +#define SDRAM_TCCD (1 - 1) + +#define SDRAM_TXSR SDRAM_TRFC /* Row cycle time after precharge */ +#define SDRAM_TMRD 1 /* Page 10, Mode Register Set */ + + +/* Last data in to row precharge, need also comply ineq on page 1648 */ +#define SDRAM_TWR max(\ + (int)max((int)SDRAM_TRDL, (int)(SDRAM_TRAS - SDRAM_TRCD)), \ + (int)(SDRAM_TRC - SDRAM_TRCD - SDRAM_TRP)\ + ) + + +#define SDRAM_MODE_BL_SHIFT 0 +#define SDRAM_MODE_CAS_SHIFT 4 +#define SDRAM_MODE_BL 0 +#define SDRAM_MODE_CAS SDRAM_CAS + +int stm32_sdram_init(void) +{ + u32 freq; + + /* + * Get frequency for NS2CLK calculation. + */ + freq = clock_get(CLOCK_AHB) / CONFIG_SYS_RAM_FREQ_DIV; + + writel(CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT + | SDRAM_CAS << FMC_SDCR_CAS_SHIFT + | SDRAM_NB << FMC_SDCR_NB_SHIFT + | SDRAM_MWID << FMC_SDCR_MWID_SHIFT + | SDRAM_NR << FMC_SDCR_NR_SHIFT + | SDRAM_NC << FMC_SDCR_NC_SHIFT + | SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT + | SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT, + &STM32_SDRAM_FMC->sdcr1); + + writel(SDRAM_TRCD << FMC_SDTR_TRCD_SHIFT + | SDRAM_TRP << FMC_SDTR_TRP_SHIFT + | SDRAM_TWR << FMC_SDTR_TWR_SHIFT + | SDRAM_TRC << FMC_SDTR_TRC_SHIFT + | SDRAM_TRAS << FMC_SDTR_TRAS_SHIFT + | SDRAM_TXSR << FMC_SDTR_TXSR_SHIFT + | SDRAM_TMRD << FMC_SDTR_TMRD_SHIFT, + &STM32_SDRAM_FMC->sdtr1); + + writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK, + &STM32_SDRAM_FMC->sdcmr); + udelay(200); /* 200 us delay, page 10, "Power-Up" */ + FMC_BUSY_WAIT(); + + writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_PRECHARGE, + &STM32_SDRAM_FMC->sdcmr); + udelay(100); + FMC_BUSY_WAIT(); + + writel((FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_AUTOREFRESH + | 7 << FMC_SDCMR_NRFS_SHIFT), &STM32_SDRAM_FMC->sdcmr); + udelay(100); + FMC_BUSY_WAIT(); + + writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT + | SDRAM_MODE_CAS << SDRAM_MODE_CAS_SHIFT) + << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE, + &STM32_SDRAM_FMC->sdcmr); + udelay(100); + FMC_BUSY_WAIT(); + + writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_NORMAL, + &STM32_SDRAM_FMC->sdcmr); + FMC_BUSY_WAIT(); + + /* Refresh timer */ + writel(SDRAM_TREF, &STM32_SDRAM_FMC->sdrtr); + + return 0; +} -- cgit v1.3.1 From 910a52ede3d7cf75b3157b9a3ef6f40879a38194 Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Mon, 10 Apr 2017 15:02:52 -0700 Subject: stm32f7: dm: add driver model support for sdram Signed-off-by: Vikas Manocha cc: Christophe KERELLO --- drivers/ram/stm32_sdram.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c index 13f896484e6..67be61f01ac 100644 --- a/drivers/ram/stm32_sdram.c +++ b/drivers/ram/stm32_sdram.c @@ -6,6 +6,8 @@ */ #include +#include +#include #include #include #include @@ -117,3 +119,32 @@ int stm32_sdram_init(void) return 0; } + +static int stm32_fmc_probe(struct udevice *dev) +{ + stm32_sdram_init(); + return 0; +} + +static int stm32_fmc_get_info(struct udevice *dev, struct ram_info *info) +{ + info->size = CONFIG_SYS_RAM_SIZE; + return 0; +} + +static struct ram_ops stm32_fmc_ops = { + .get_info = stm32_fmc_get_info, +}; + +static const struct udevice_id stm32_fmc_ids[] = { + { .compatible = "st,stm32-fmc" }, + { } +}; + +U_BOOT_DRIVER(stm32_fmc) = { + .name = "stm32_fmc", + .id = UCLASS_RAM, + .of_match = stm32_fmc_ids, + .ops = &stm32_fmc_ops, + .probe = stm32_fmc_probe, +}; -- cgit v1.3.1 From d0b24c1aa96729d4d9fee02e2c60fc920068c6c5 Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Mon, 10 Apr 2017 15:02:55 -0700 Subject: stm32f7: use clock driver to enable sdram controller clock This patch also removes the sdram/fmc clock enable from board specific code. Signed-off-by: Vikas Manocha cc: Christophe KERELLO --- arch/arm/dts/stm32f746.dtsi | 1 + board/st/stm32f746-disco/stm32f746-disco.c | 2 -- drivers/ram/stm32_sdram.c | 15 +++++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi index 3707550b039..e9fd6f4e2ef 100644 --- a/arch/arm/dts/stm32f746.dtsi +++ b/arch/arm/dts/stm32f746.dtsi @@ -74,6 +74,7 @@ fmc: fmc@A0000000 { compatible = "st,stm32-fmc"; reg = <0xA0000000 0x1000>; + clocks = <&rcc 0 64>; u-boot,dm-pre-reloc; }; diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c index e1113a6989b..370db15bea9 100644 --- a/board/st/stm32f746-disco/stm32f746-disco.c +++ b/board/st/stm32f746-disco/stm32f746-disco.c @@ -51,8 +51,6 @@ int dram_init(void) if (rv) return rv; - clock_setup(FMC_CLOCK_CFG); - rv = uclass_get_device(UCLASS_RAM, 0, &dev); if (rv) { debug("DRAM init failed: %d\n", rv); diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c index 67be61f01ac..67d885572d6 100644 --- a/drivers/ram/stm32_sdram.c +++ b/drivers/ram/stm32_sdram.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -122,6 +123,20 @@ int stm32_sdram_init(void) static int stm32_fmc_probe(struct udevice *dev) { +#ifdef CONFIG_CLK + int ret; + struct clk clk; + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) + return ret; + + ret = clk_enable(&clk); + + if (ret) { + dev_err(dev, "failed to enable clock\n"); + return ret; + } +#endif stm32_sdram_init(); return 0; } -- cgit v1.3.1 From 6c9a10034a21680c4b2595d9b6468a767dedebca Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Mon, 10 Apr 2017 15:02:56 -0700 Subject: stm32f7: sdram: use sdram device tree node to configure sdram controller Signed-off-by: Vikas Manocha cc: Christophe KERELLO --- arch/arm/dts/stm32f746-disco.dts | 10 +++ drivers/ram/stm32_sdram.c | 144 +++++++++++++++++++------------ include/dt-bindings/memory/stm32-sdram.h | 34 ++++++++ 3 files changed, 135 insertions(+), 53 deletions(-) create mode 100644 include/dt-bindings/memory/stm32-sdram.h (limited to 'drivers') diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts index 5846b0d7e74..f098d2eba31 100644 --- a/arch/arm/dts/stm32f746-disco.dts +++ b/arch/arm/dts/stm32f746-disco.dts @@ -47,6 +47,7 @@ /dts-v1/; #include "stm32f746.dtsi" +#include / { model = "STMicroelectronics STM32F746-DISCO board"; @@ -81,6 +82,15 @@ pinctrl-0 = <&fmc_pins>; pinctrl-names = "default"; status = "okay"; + + mr-nbanks = <1>; + /* sdram memory configuration from sdram datasheet IS42S16400J */ + bank1: bank@0 { + st,sdram-control = /bits/ 8 ; + st,sdram-timing = /bits/ 8 ; + }; }; &mac { diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c index 67d885572d6..eb1ab945b50 100644 --- a/drivers/ram/stm32_sdram.c +++ b/drivers/ram/stm32_sdram.c @@ -13,6 +13,31 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + +struct stm32_sdram_control { + u8 no_columns; + u8 no_rows; + u8 memory_width; + u8 no_banks; + u8 cas_latency; + u8 rd_burst; + u8 rd_pipe_delay; +}; + +struct stm32_sdram_timing { + u8 tmrd; + u8 txsr; + u8 tras; + u8 trc; + u8 trp; + u8 trcd; +}; +struct stm32_sdram_params { + u8 no_sdram_banks; + struct stm32_sdram_control sdram_control; + struct stm32_sdram_timing sdram_timing; +}; static inline u32 _ns2clk(u32 ns, u32 freq) { u32 tmp = freq/1000000; @@ -21,73 +46,53 @@ static inline u32 _ns2clk(u32 ns, u32 freq) #define NS2CLK(ns) (_ns2clk(ns, freq)) -/* - * Following are timings for IS42S16400J, from corresponding datasheet - */ -#define SDRAM_CAS 3 /* 3 cycles */ -#define SDRAM_NB 1 /* Number of banks */ -#define SDRAM_MWID 1 /* 16 bit memory */ - -#define SDRAM_NR 0x1 /* 12-bit row */ -#define SDRAM_NC 0x0 /* 8-bit col */ -#define SDRAM_RBURST 0x1 /* Single read requests always as bursts */ -#define SDRAM_RPIPE 0x0 /* No HCLK clock cycle delay */ - -#define SDRAM_TRRD NS2CLK(12) -#define SDRAM_TRCD NS2CLK(18) -#define SDRAM_TRP NS2CLK(18) -#define SDRAM_TRAS NS2CLK(42) -#define SDRAM_TRC NS2CLK(60) -#define SDRAM_TRFC NS2CLK(60) -#define SDRAM_TCDL (1 - 1) -#define SDRAM_TRDL NS2CLK(12) -#define SDRAM_TBDL (1 - 1) #define SDRAM_TREF (NS2CLK(64000000 / 8192) - 20) -#define SDRAM_TCCD (1 - 1) - -#define SDRAM_TXSR SDRAM_TRFC /* Row cycle time after precharge */ -#define SDRAM_TMRD 1 /* Page 10, Mode Register Set */ - - -/* Last data in to row precharge, need also comply ineq on page 1648 */ -#define SDRAM_TWR max(\ - (int)max((int)SDRAM_TRDL, (int)(SDRAM_TRAS - SDRAM_TRCD)), \ - (int)(SDRAM_TRC - SDRAM_TRCD - SDRAM_TRP)\ - ) - #define SDRAM_MODE_BL_SHIFT 0 #define SDRAM_MODE_CAS_SHIFT 4 #define SDRAM_MODE_BL 0 -#define SDRAM_MODE_CAS SDRAM_CAS +#define SDRAM_MODE_CAS 3 + +#define SDRAM_TRDL 12 -int stm32_sdram_init(void) +int stm32_sdram_init(struct udevice *dev) { u32 freq; + u32 sdram_twr; + struct stm32_sdram_params *params = dev_get_platdata(dev); /* * Get frequency for NS2CLK calculation. */ freq = clock_get(CLOCK_AHB) / CONFIG_SYS_RAM_FREQ_DIV; + debug("%s, sdram freq = %d\n", __func__, freq); + + /* Last data in to row precharge, need also comply ineq on page 1648 */ + sdram_twr = max( + max(SDRAM_TRDL, params->sdram_timing.tras + - params->sdram_timing.trcd), + params->sdram_timing.trc - params->sdram_timing.trcd + - params->sdram_timing.trp + ); writel(CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT - | SDRAM_CAS << FMC_SDCR_CAS_SHIFT - | SDRAM_NB << FMC_SDCR_NB_SHIFT - | SDRAM_MWID << FMC_SDCR_MWID_SHIFT - | SDRAM_NR << FMC_SDCR_NR_SHIFT - | SDRAM_NC << FMC_SDCR_NC_SHIFT - | SDRAM_RPIPE << FMC_SDCR_RPIPE_SHIFT - | SDRAM_RBURST << FMC_SDCR_RBURST_SHIFT, - &STM32_SDRAM_FMC->sdcr1); - - writel(SDRAM_TRCD << FMC_SDTR_TRCD_SHIFT - | SDRAM_TRP << FMC_SDTR_TRP_SHIFT - | SDRAM_TWR << FMC_SDTR_TWR_SHIFT - | SDRAM_TRC << FMC_SDTR_TRC_SHIFT - | SDRAM_TRAS << FMC_SDTR_TRAS_SHIFT - | SDRAM_TXSR << FMC_SDTR_TXSR_SHIFT - | SDRAM_TMRD << FMC_SDTR_TMRD_SHIFT, - &STM32_SDRAM_FMC->sdtr1); + | params->sdram_control.cas_latency << FMC_SDCR_CAS_SHIFT + | params->sdram_control.no_banks << FMC_SDCR_NB_SHIFT + | params->sdram_control.memory_width << FMC_SDCR_MWID_SHIFT + | params->sdram_control.no_rows << FMC_SDCR_NR_SHIFT + | params->sdram_control.no_columns << FMC_SDCR_NC_SHIFT + | params->sdram_control.rd_pipe_delay << FMC_SDCR_RPIPE_SHIFT + | params->sdram_control.rd_burst << FMC_SDCR_RBURST_SHIFT, + &STM32_SDRAM_FMC->sdcr1); + + writel(NS2CLK(params->sdram_timing.trcd) << FMC_SDTR_TRCD_SHIFT + | NS2CLK(params->sdram_timing.trp) << FMC_SDTR_TRP_SHIFT + | NS2CLK(sdram_twr) << FMC_SDTR_TWR_SHIFT + | NS2CLK(params->sdram_timing.trc) << FMC_SDTR_TRC_SHIFT + | NS2CLK(params->sdram_timing.tras) << FMC_SDTR_TRAS_SHIFT + | NS2CLK(params->sdram_timing.txsr) << FMC_SDTR_TXSR_SHIFT + | NS2CLK(params->sdram_timing.tmrd) << FMC_SDTR_TMRD_SHIFT, + &STM32_SDRAM_FMC->sdtr1); writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK, &STM32_SDRAM_FMC->sdcmr); @@ -121,11 +126,39 @@ int stm32_sdram_init(void) return 0; } +static int stm32_fmc_ofdata_to_platdata(struct udevice *dev) +{ + int ret; + int node = dev->of_offset; + const void *blob = gd->fdt_blob; + struct stm32_sdram_params *params = dev_get_platdata(dev); + + params->no_sdram_banks = fdtdec_get_uint(blob, node, "mr-nbanks", 1); + debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks); + + fdt_for_each_subnode(node, blob, node) { + ret = fdtdec_get_byte_array(blob, node, "st,sdram-control", + (u8 *)¶ms->sdram_control, + sizeof(params->sdram_control)); + if (ret) + return ret; + + ret = fdtdec_get_byte_array(blob, node, "st,sdram-timing", + (u8 *)¶ms->sdram_timing, + sizeof(params->sdram_timing)); + if (ret) + return ret; + } + + return 0; +} + static int stm32_fmc_probe(struct udevice *dev) { #ifdef CONFIG_CLK int ret; struct clk clk; + ret = clk_get_by_index(dev, 0, &clk); if (ret < 0) return ret; @@ -137,7 +170,10 @@ static int stm32_fmc_probe(struct udevice *dev) return ret; } #endif - stm32_sdram_init(); + ret = stm32_sdram_init(dev); + if (ret) + return ret; + return 0; } @@ -161,5 +197,7 @@ U_BOOT_DRIVER(stm32_fmc) = { .id = UCLASS_RAM, .of_match = stm32_fmc_ids, .ops = &stm32_fmc_ops, + .ofdata_to_platdata = stm32_fmc_ofdata_to_platdata, .probe = stm32_fmc_probe, + .platdata_auto_alloc_size = sizeof(struct stm32_sdram_params), }; diff --git a/include/dt-bindings/memory/stm32-sdram.h b/include/dt-bindings/memory/stm32-sdram.h new file mode 100644 index 00000000000..4cd6c2b77cb --- /dev/null +++ b/include/dt-bindings/memory/stm32-sdram.h @@ -0,0 +1,34 @@ +#ifndef DT_BINDINGS_STM32_SDRAM_H +#define DT_BINDINGS_STM32_SDRAM_H + +#define NO_COL_8 0x0 +#define NO_COL_9 0x1 +#define NO_COL_10 0x2 +#define NO_COL_11 0x3 + +#define NO_ROW_11 0x0 +#define NO_ROW_12 0x1 +#define NO_ROW_13 0x2 + +#define MWIDTH_8 0x0 +#define MWIDTH_16 0x1 +#define MWIDTH_32 0x2 +#define BANKS_2 0x0 +#define BANKS_4 0x1 +#define CAS_1 0x1 +#define CAS_2 0x2 +#define CAS_3 0x3 +#define RD_BURST_EN 0x1 +#define RD_BURST_DIS 0x0 +#define RD_PIPE_DL_0 0x0 +#define RD_PIPE_DL_1 0x1 +#define RD_PIPE_DL_2 0x2 + +#define TMRD_1 0x1 +#define TXSR_60 60 +#define TRAS_42 42 +#define TRC_60 60 +#define TRP_18 18 +#define TRCD_18 18 + +#endif -- cgit v1.3.1 From 774171020beaf3af19dcc8056c9de38653bc121b Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Mon, 10 Apr 2017 15:02:57 -0700 Subject: dm: gpio: Add driver for stm32f7 gpio controller This patch adds gpio driver supporting driver model for stm32f7 gpio. Signed-off-by: Vikas Manocha Reviewed-by: Simon Glass Cc: Christophe KERELLO [trini: Add depends on STM32] Signed-off-by: Tom Rini --- arch/arm/include/asm/arch-stm32f7/gpio.h | 20 ++++- drivers/gpio/Kconfig | 9 +++ drivers/gpio/Makefile | 1 + drivers/gpio/stm32f7_gpio.c | 135 +++++++++++++++++++++++++++++++ drivers/pinctrl/pinctrl_stm32.c | 38 ++++++++- 5 files changed, 198 insertions(+), 5 deletions(-) create mode 100644 drivers/gpio/stm32f7_gpio.c (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-stm32f7/gpio.h b/arch/arm/include/asm/arch-stm32f7/gpio.h index 2942cd923c0..45999b4d2e3 100644 --- a/arch/arm/include/asm/arch-stm32f7/gpio.h +++ b/arch/arm/include/asm/arch-stm32f7/gpio.h @@ -96,6 +96,22 @@ struct stm32_gpio_ctl { enum stm32_gpio_af af; }; +struct stm32_gpio_regs { + u32 moder; /* GPIO port mode */ + u32 otyper; /* GPIO port output type */ + u32 ospeedr; /* GPIO port output speed */ + u32 pupdr; /* GPIO port pull-up/pull-down */ + u32 idr; /* GPIO port input data */ + u32 odr; /* GPIO port output data */ + u32 bsrr; /* GPIO port bit set/reset */ + u32 lckr; /* GPIO port configuration lock */ + u32 afr[2]; /* GPIO alternate function */ +}; + +struct stm32_gpio_priv { + struct stm32_gpio_regs *regs; +}; + static inline unsigned stm32_gpio_to_port(unsigned gpio) { return gpio / 16; @@ -106,8 +122,4 @@ static inline unsigned stm32_gpio_to_pin(unsigned gpio) return gpio % 16; } -int stm32_gpio_config(const struct stm32_gpio_dsc *gpio_dsc, - const struct stm32_gpio_ctl *gpio_ctl); -int stm32_gpout_set(const struct stm32_gpio_dsc *gpio_dsc, int state); - #endif /* _STM32_GPIO_H_ */ diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c95e9acd5f7..99516119ff1 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -171,6 +171,15 @@ config PIC32_GPIO help Say yes here to support Microchip PIC32 GPIOs. +config STM32F7_GPIO + bool "ST STM32 GPIO driver" + depends on DM_GPIO && STM32 + default y + help + Device model driver support for STM32 GPIO controller. It should be + usable on many stm32 families like stm32f4 & stm32H7. + Tested on STM32F7. + config MVEBU_GPIO bool "Marvell MVEBU GPIO driver" depends on DM_GPIO && ARCH_MVEBU diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 27f8068e3e6..0ca845f54ca 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -49,6 +49,7 @@ oby-$(CONFIG_SX151X) += sx151x.o obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o obj-$(CONFIG_LPC32XX_GPIO) += lpc32xx_gpio.o obj-$(CONFIG_STM32_GPIO) += stm32_gpio.o +obj-$(CONFIG_STM32F7_GPIO) += stm32f7_gpio.o obj-$(CONFIG_GPIO_UNIPHIER) += gpio-uniphier.o obj-$(CONFIG_ZYNQ_GPIO) += zynq_gpio.o obj-$(CONFIG_VYBRID_GPIO) += vybrid_gpio.o diff --git a/drivers/gpio/stm32f7_gpio.c b/drivers/gpio/stm32f7_gpio.c new file mode 100644 index 00000000000..5e0546357f9 --- /dev/null +++ b/drivers/gpio/stm32f7_gpio.c @@ -0,0 +1,135 @@ +/* + * (C) Copyright 2017 + * Vikas Manocha, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_SIZE_BANK_NAME 5 +#define STM32_GPIOS_PER_BANK 16 +#define MODE_BITS(gpio_pin) (gpio_pin * 2) +#define MODE_BITS_MASK 3 +#define IN_OUT_BIT_INDEX(gpio_pin) (1UL << (gpio_pin)) + +DECLARE_GLOBAL_DATA_PTR; + +static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; + int bits_index = MODE_BITS(offset); + int mask = MODE_BITS_MASK << bits_index; + + clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_IN << bits_index); + + return 0; +} + +static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; + int bits_index = MODE_BITS(offset); + int mask = MODE_BITS_MASK << bits_index; + + clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_OUT << bits_index); + mask = IN_OUT_BIT_INDEX(offset); + clrsetbits_le32(®s->odr, mask, value ? mask : 0); + + return 0; +} + +static int stm32_gpio_get_value(struct udevice *dev, unsigned offset) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; + + return readl(®s->idr) & IN_OUT_BIT_INDEX(offset) ? 1 : 0; +} + +static int stm32_gpio_set_value(struct udevice *dev, unsigned offset, int value) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; + int mask = IN_OUT_BIT_INDEX(offset); + + clrsetbits_le32(®s->odr, mask, value ? mask : 0); + + return 0; +} + +static const struct dm_gpio_ops gpio_stm32_ops = { + .direction_input = stm32_gpio_direction_input, + .direction_output = stm32_gpio_direction_output, + .get_value = stm32_gpio_get_value, + .set_value = stm32_gpio_set_value, +}; + +static int gpio_stm32_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct stm32_gpio_priv *priv = dev_get_priv(dev); + fdt_addr_t addr; + char *name; + + addr = dev_get_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->regs = (struct stm32_gpio_regs *)addr; + name = (char *)fdtdec_locate_byte_array(gd->fdt_blob, + dev_of_offset(dev), + "st,bank-name", + MAX_SIZE_BANK_NAME); + if (!name) + return -EINVAL; + uc_priv->bank_name = name; + uc_priv->gpio_count = STM32_GPIOS_PER_BANK; + debug("%s, addr = 0x%p, bank_name = %s\n", __func__, (u32 *)priv->regs, + uc_priv->bank_name); + +#ifdef CONFIG_CLK + struct clk clk; + int ret; + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) + return ret; + + ret = clk_enable(&clk); + + if (ret) { + dev_err(dev, "failed to enable clock\n"); + return ret; + } + debug("clock enabled for device %s\n", dev->name); +#endif + + return 0; +} + +static const struct udevice_id stm32_gpio_ids[] = { + { .compatible = "st,stm32-gpio" }, + { } +}; + +U_BOOT_DRIVER(gpio_stm32) = { + .name = "gpio_stm32", + .id = UCLASS_GPIO, + .of_match = stm32_gpio_ids, + .probe = gpio_stm32_probe, + .ops = &gpio_stm32_ops, + .flags = DM_FLAG_PRE_RELOC | DM_UC_FLAG_SEQ_ALIAS, + .priv_auto_alloc_size = sizeof(struct stm32_gpio_priv), +}; diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index aa2c440b143..0e74d051c30 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -1,10 +1,45 @@ #include -#include #include #include +#include +#include +#include DECLARE_GLOBAL_DATA_PTR; +#define MODE_BITS_MASK 3 +#define OSPEED_MASK 3 +#define PUPD_MASK 3 +#define OTYPE_MSK 1 +#define AFR_MASK 0xF + +static int stm32_gpio_config(struct gpio_desc *desc, + const struct stm32_gpio_ctl *ctl) +{ + struct stm32_gpio_priv *priv = dev_get_priv(desc->dev); + struct stm32_gpio_regs *regs = priv->regs; + u32 index; + + if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 || + ctl->pupd > 2 || ctl->speed > 3) + return -EINVAL; + + index = (desc->offset & 0x07) * 4; + clrsetbits_le32(®s->afr[desc->offset >> 3], AFR_MASK << index, + ctl->af << index); + + index = desc->offset * 2; + clrsetbits_le32(®s->moder, MODE_BITS_MASK << index, + ctl->mode << index); + clrsetbits_le32(®s->ospeedr, OSPEED_MASK << index, + ctl->speed << index); + clrsetbits_le32(®s->pupdr, PUPD_MASK << index, ctl->pupd << index); + + index = desc->offset; + clrsetbits_le32(®s->otyper, OTYPE_MSK << index, ctl->otype << index); + + return 0; +} static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin) { gpio_dsc->port = (port_pin & 0xF000) >> 12; @@ -18,6 +53,7 @@ static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin) static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn, int node) { gpio_fn &= 0x00FF; + gpio_ctl->af = 0; switch (gpio_fn) { case 0: -- cgit v1.3.1 From 280057bd7dd623420b2d8b383fe5bbe26820bc93 Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Mon, 10 Apr 2017 15:02:59 -0700 Subject: stm32f7: use stm32f7 gpio driver supporting driver model With this gpio driver supporting DM, there is no need to enable clocks for different gpios (for pin muxing) in the board specific code. Need to increase the allocatable area required before relocation from 0x400 to 0xC00 becuase of 10 new gpio devices(& new gpio class) added in device tree. Signed-off-by: Vikas Manocha cc: Christophe KERELLO Reviewed-by: Simon Glass --- arch/arm/include/asm/arch-stm32f7/gpio.h | 1 + board/st/stm32f746-disco/stm32f746-disco.c | 70 ++---------------------------- configs/stm32f746-disco_defconfig | 4 ++ drivers/clk/clk_stm32f7.c | 39 ----------------- drivers/pinctrl/pinctrl_stm32.c | 9 +++- include/configs/stm32f746-disco.h | 1 - 6 files changed, 15 insertions(+), 109 deletions(-) (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-stm32f7/gpio.h b/arch/arm/include/asm/arch-stm32f7/gpio.h index 45999b4d2e3..56e469e3023 100644 --- a/arch/arm/include/asm/arch-stm32f7/gpio.h +++ b/arch/arm/include/asm/arch-stm32f7/gpio.h @@ -7,6 +7,7 @@ #ifndef _STM32_GPIO_H_ #define _STM32_GPIO_H_ +#include enum stm32_gpio_port { STM32_GPIO_PORT_A = 0, diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c index 370db15bea9..45a2c47aa28 100644 --- a/board/st/stm32f746-disco/stm32f746-disco.c +++ b/board/st/stm32f746-disco/stm32f746-disco.c @@ -20,37 +20,12 @@ DECLARE_GLOBAL_DATA_PTR; -const struct stm32_gpio_ctl gpio_ctl_gpout = { - .mode = STM32_GPIO_MODE_OUT, - .otype = STM32_GPIO_OTYPE_PP, - .speed = STM32_GPIO_SPEED_50M, - .pupd = STM32_GPIO_PUPD_NO, - .af = STM32_GPIO_AF0 -}; - -static int fmc_setup_gpio(void) -{ - clock_setup(GPIO_B_CLOCK_CFG); - clock_setup(GPIO_C_CLOCK_CFG); - clock_setup(GPIO_D_CLOCK_CFG); - clock_setup(GPIO_E_CLOCK_CFG); - clock_setup(GPIO_F_CLOCK_CFG); - clock_setup(GPIO_G_CLOCK_CFG); - clock_setup(GPIO_H_CLOCK_CFG); - - return 0; -} - int dram_init(void) { struct udevice *dev; struct ram_info ram; int rv; - rv = fmc_setup_gpio(); - if (rv) - return rv; - rv = uclass_get_device(UCLASS_RAM, 0, &dev); if (rv) { debug("DRAM init failed: %d\n", rv); @@ -73,37 +48,21 @@ int dram_init(void) return rv; } -int uart_setup_gpio(void) -{ - clock_setup(GPIO_A_CLOCK_CFG); - clock_setup(GPIO_B_CLOCK_CFG); - return 0; -} - #ifdef CONFIG_ETH_DESIGNWARE - static int stmmac_setup(void) { clock_setup(SYSCFG_CLOCK_CFG); /* Set >RMII mode */ STM32_SYSCFG->pmc |= SYSCFG_PMC_MII_RMII_SEL; - - clock_setup(GPIO_A_CLOCK_CFG); - clock_setup(GPIO_C_CLOCK_CFG); - clock_setup(GPIO_G_CLOCK_CFG); clock_setup(STMMAC_CLOCK_CFG); return 0; } -#endif -#ifdef CONFIG_STM32_QSPI - -static int qspi_setup(void) +int board_early_init_f(void) { - clock_setup(GPIO_B_CLOCK_CFG); - clock_setup(GPIO_D_CLOCK_CFG); - clock_setup(GPIO_E_CLOCK_CFG); + stmmac_setup(); + return 0; } #endif @@ -113,29 +72,6 @@ u32 get_board_rev(void) return 0; } -int board_early_init_f(void) -{ - int res; - - res = uart_setup_gpio(); - if (res) - return res; - -#ifdef CONFIG_ETH_DESIGNWARE - res = stmmac_setup(); - if (res) - return res; -#endif - -#ifdef CONFIG_STM32_QSPI - res = qspi_setup(); - if (res) - return res; -#endif - - return 0; -} - int board_init(void) { gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; diff --git a/configs/stm32f746-disco_defconfig b/configs/stm32f746-disco_defconfig index 57a0d610df3..4322aad14d2 100644 --- a/configs/stm32f746-disco_defconfig +++ b/configs/stm32f746-disco_defconfig @@ -24,6 +24,7 @@ CONFIG_CMD_DNS=y CONFIG_CMD_LINK_LOCAL=y CONFIG_CMD_TIMER=y CONFIG_OF_CONTROL=y +CONFIG_DM_SEQ_ALIAS=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_NETCONSOLE=y CONFIG_CLK=y @@ -49,3 +50,6 @@ CONFIG_PINCTRL=y CONFIG_PINCTRL_STM32=y CONFIG_RAM=y CONFIG_STM32_SDRAM=y +CONFIG_DM_GPIO=y +CONFIG_STM32F7_GPIO=y +CONFIG_SYS_MALLOC_F_LEN=0xC00 diff --git a/drivers/clk/clk_stm32f7.c b/drivers/clk/clk_stm32f7.c index 0d86395d476..da3c204ff50 100644 --- a/drivers/clk/clk_stm32f7.c +++ b/drivers/clk/clk_stm32f7.c @@ -228,56 +228,17 @@ static int stm32_clk_enable(struct clk *clk) void clock_setup(int peripheral) { switch (peripheral) { - case GPIO_A_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_A_EN); - break; - case GPIO_B_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_B_EN); - break; - case GPIO_C_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_C_EN); - break; - case GPIO_D_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_D_EN); - break; - case GPIO_E_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_E_EN); - break; - case GPIO_F_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_F_EN); - break; - case GPIO_G_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_G_EN); - break; - case GPIO_H_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_H_EN); - break; - case GPIO_I_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_I_EN); - break; - case GPIO_J_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_J_EN); - break; - case GPIO_K_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_GPIO_K_EN); - break; case SYSCFG_CLOCK_CFG: setbits_le32(&STM32_RCC->apb2enr, RCC_APB2ENR_SYSCFGEN); break; case TIMER2_CLOCK_CFG: setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_TIM2EN); break; - case FMC_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb3enr, RCC_AHB3ENR_FMC_EN); - break; case STMMAC_CLOCK_CFG: setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_EN); setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_RX_EN); setbits_le32(&STM32_RCC->ahb1enr, RCC_AHB1ENR_ETHMAC_TX_EN); break; - case QSPI_CLOCK_CFG: - setbits_le32(&STM32_RCC->ahb3enr, RCC_AHB3ENR_QSPI_EN); - break; default: break; } diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 0e74d051c30..01f0429a399 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -121,11 +121,16 @@ static int stm32_pinctrl_set_state_simple(struct udevice *dev, if (len < 0) return -EINVAL; for (i = 0; i < len; i++) { + struct gpio_desc desc; debug("%s: pinmux = %x\n", __func__, *(pin_mux + i)); prep_gpio_dsc(&gpio_dsc, *(pin_mux + i)); prep_gpio_ctl(&gpio_ctl, *(pin_mux + i), args.node); - - rv = stm32_gpio_config(&gpio_dsc, &gpio_ctl); + rv = uclass_get_device_by_seq(UCLASS_GPIO, + gpio_dsc.port, &desc.dev); + if (rv) + return rv; + desc.offset = gpio_dsc.pin; + rv = stm32_gpio_config(&desc, &gpio_ctl); debug("%s: rv = %d\n\n", __func__, rv); if (rv) return rv; diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h index de3d661d60a..e917ba9162f 100644 --- a/include/configs/stm32f746-disco.h +++ b/include/configs/stm32f746-disco.h @@ -30,7 +30,6 @@ #define CONFIG_ENV_IS_NOWHERE #define CONFIG_ENV_SIZE (8 << 10) -#define CONFIG_STM32_GPIO #define CONFIG_STM32_FLASH #define CONFIG_STM32X7_SERIAL -- cgit v1.3.1 From 57af3cc32a7b39bc26987780fbca109e206d1c34 Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Mon, 10 Apr 2017 15:03:01 -0700 Subject: stm32f7: stm32f746-disco: read memory info from device tree Signed-off-by: Vikas Manocha cc: Christophe KERELLO --- board/st/stm32f746-disco/stm32f746-disco.c | 42 +++++++++++++++++++++--------- drivers/ram/stm32_sdram.c | 1 - include/configs/stm32f746-disco.h | 6 +---- 3 files changed, 31 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/board/st/stm32f746-disco/stm32f746-disco.c b/board/st/stm32f746-disco/stm32f746-disco.c index 52c1900ee34..dc3a9dcade0 100644 --- a/board/st/stm32f746-disco/stm32f746-disco.c +++ b/board/st/stm32f746-disco/stm32f746-disco.c @@ -21,32 +21,51 @@ DECLARE_GLOBAL_DATA_PTR; +int get_memory_base_size(fdt_addr_t *mr_base, fdt_addr_t *mr_size) +{ + int mr_node; + + mr_node = fdt_path_offset(gd->fdt_blob, "/memory"); + if (mr_node < 0) + return mr_node; + *mr_base = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, mr_node, + "reg", 0, mr_size, false); + debug("mr_base = %lx, mr_size= %lx\n", *mr_base, *mr_size); + + return 0; +} int dram_init(void) { struct udevice *dev; - struct ram_info ram; int rv; + fdt_addr_t mr_base, mr_size; rv = uclass_get_device(UCLASS_RAM, 0, &dev); if (rv) { debug("DRAM init failed: %d\n", rv); return rv; } - rv = ram_get_info(dev, &ram); - if (rv) { - debug("Cannot get DRAM size: %d\n", rv); + + rv = get_memory_base_size(&mr_base, &mr_size); + if (rv) return rv; - } - debug("SDRAM base=%lx, size=%x\n", ram.base, ram.size); - gd->ram_size = ram.size; + gd->ram_size = mr_size; + gd->ram_top = mr_base; + return rv; +} + +int dram_init_banksize(void) +{ + fdt_addr_t mr_base, mr_size; + get_memory_base_size(&mr_base, &mr_size); /* * Fill in global info with description of SRAM configuration */ - gd->bd->bi_dram[0].start = CONFIG_SYS_RAM_BASE; - gd->bd->bi_dram[0].size = ram.size; + gd->bd->bi_dram[0].start = mr_base; + gd->bd->bi_dram[0].size = mr_size; - return rv; + return 0; } #ifdef CONFIG_ETH_DESIGNWARE @@ -111,7 +130,6 @@ int board_late_init(void) int board_init(void) { - gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; - + gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100; return 0; } diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c index eb1ab945b50..5e09f35b919 100644 --- a/drivers/ram/stm32_sdram.c +++ b/drivers/ram/stm32_sdram.c @@ -179,7 +179,6 @@ static int stm32_fmc_probe(struct udevice *dev) static int stm32_fmc_get_info(struct udevice *dev, struct ram_info *info) { - info->size = CONFIG_SYS_RAM_SIZE; return 0; } diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h index 48ac4413e02..349ee3af89e 100644 --- a/include/configs/stm32f746-disco.h +++ b/include/configs/stm32f746-disco.h @@ -16,11 +16,7 @@ * Configuration of the external SDRAM memory */ #define CONFIG_NR_DRAM_BANKS 1 -#define CONFIG_SYS_RAM_SIZE (8 * 1024 * 1024) -#define CONFIG_SYS_RAM_CS 1 -#define CONFIG_SYS_RAM_FREQ_DIV 2 -#define CONFIG_SYS_RAM_BASE 0xC0000000 -#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_RAM_BASE +#define CONFIG_SYS_RAM_FREQ_DIV 2 #define CONFIG_SYS_LOAD_ADDR 0xC0400000 #define CONFIG_LOADADDR 0xC0400000 -- cgit v1.3.1 From bfea69ad27936d619c0eb3c1be55cc292df8d7f5 Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Mon, 10 Apr 2017 15:03:03 -0700 Subject: stm32f7: sdram: correct sdram configuration as per micron sdram Actually the sdram memory on stm32f746 discovery board is micron part MT48LC_4M32_B2B5_6A. This patch does the modification required in the device tree node & driver for the same. Also we are passing here all the timing parameters in terms of clock cycles, so no need to convert time(ns or ms) to cycles. Signed-off-by: Vikas Manocha cc: Christophe KERELLO --- arch/arm/dts/stm32f746-disco.dts | 13 +++++--- drivers/ram/stm32_sdram.c | 55 ++++++++++---------------------- include/configs/stm32f746-disco.h | 1 - include/dt-bindings/memory/stm32-sdram.h | 15 +++++---- 4 files changed, 33 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts index 8e4576bdc1f..e720ff12078 100644 --- a/arch/arm/dts/stm32f746-disco.dts +++ b/arch/arm/dts/stm32f746-disco.dts @@ -106,12 +106,15 @@ status = "okay"; mr-nbanks = <1>; - /* sdram memory configuration from sdram datasheet IS42S16400J */ + /* Memory configuration from sdram datasheet MT48LC_4M32_B2B5-6A */ bank1: bank@0 { - st,sdram-control = /bits/ 8 ; - st,sdram-timing = /bits/ 8 ; + st,sdram-control = /bits/ 8 ; + st,sdram-timing = /bits/ 8 ; + /* refcount = (64msec/total_row_sdram)*freq - 20 */ + st,sdram-refcount = < 1542 >; }; }; diff --git a/drivers/ram/stm32_sdram.c b/drivers/ram/stm32_sdram.c index 5e09f35b919..48b4979e624 100644 --- a/drivers/ram/stm32_sdram.c +++ b/drivers/ram/stm32_sdram.c @@ -21,6 +21,7 @@ struct stm32_sdram_control { u8 memory_width; u8 no_banks; u8 cas_latency; + u8 sdclk; u8 rd_burst; u8 rd_pipe_delay; }; @@ -31,51 +32,25 @@ struct stm32_sdram_timing { u8 tras; u8 trc; u8 trp; + u8 twr; u8 trcd; }; struct stm32_sdram_params { u8 no_sdram_banks; struct stm32_sdram_control sdram_control; struct stm32_sdram_timing sdram_timing; + u32 sdram_ref_count; }; -static inline u32 _ns2clk(u32 ns, u32 freq) -{ - u32 tmp = freq/1000000; - return (tmp * ns) / 1000; -} - -#define NS2CLK(ns) (_ns2clk(ns, freq)) - -#define SDRAM_TREF (NS2CLK(64000000 / 8192) - 20) #define SDRAM_MODE_BL_SHIFT 0 #define SDRAM_MODE_CAS_SHIFT 4 #define SDRAM_MODE_BL 0 -#define SDRAM_MODE_CAS 3 - -#define SDRAM_TRDL 12 int stm32_sdram_init(struct udevice *dev) { - u32 freq; - u32 sdram_twr; struct stm32_sdram_params *params = dev_get_platdata(dev); - /* - * Get frequency for NS2CLK calculation. - */ - freq = clock_get(CLOCK_AHB) / CONFIG_SYS_RAM_FREQ_DIV; - debug("%s, sdram freq = %d\n", __func__, freq); - - /* Last data in to row precharge, need also comply ineq on page 1648 */ - sdram_twr = max( - max(SDRAM_TRDL, params->sdram_timing.tras - - params->sdram_timing.trcd), - params->sdram_timing.trc - params->sdram_timing.trcd - - params->sdram_timing.trp - ); - - writel(CONFIG_SYS_RAM_FREQ_DIV << FMC_SDCR_SDCLK_SHIFT + writel(params->sdram_control.sdclk << FMC_SDCR_SDCLK_SHIFT | params->sdram_control.cas_latency << FMC_SDCR_CAS_SHIFT | params->sdram_control.no_banks << FMC_SDCR_NB_SHIFT | params->sdram_control.memory_width << FMC_SDCR_MWID_SHIFT @@ -85,13 +60,13 @@ int stm32_sdram_init(struct udevice *dev) | params->sdram_control.rd_burst << FMC_SDCR_RBURST_SHIFT, &STM32_SDRAM_FMC->sdcr1); - writel(NS2CLK(params->sdram_timing.trcd) << FMC_SDTR_TRCD_SHIFT - | NS2CLK(params->sdram_timing.trp) << FMC_SDTR_TRP_SHIFT - | NS2CLK(sdram_twr) << FMC_SDTR_TWR_SHIFT - | NS2CLK(params->sdram_timing.trc) << FMC_SDTR_TRC_SHIFT - | NS2CLK(params->sdram_timing.tras) << FMC_SDTR_TRAS_SHIFT - | NS2CLK(params->sdram_timing.txsr) << FMC_SDTR_TXSR_SHIFT - | NS2CLK(params->sdram_timing.tmrd) << FMC_SDTR_TMRD_SHIFT, + writel(params->sdram_timing.trcd << FMC_SDTR_TRCD_SHIFT + | params->sdram_timing.trp << FMC_SDTR_TRP_SHIFT + | params->sdram_timing.twr << FMC_SDTR_TWR_SHIFT + | params->sdram_timing.trc << FMC_SDTR_TRC_SHIFT + | params->sdram_timing.tras << FMC_SDTR_TRAS_SHIFT + | params->sdram_timing.txsr << FMC_SDTR_TXSR_SHIFT + | params->sdram_timing.tmrd << FMC_SDTR_TMRD_SHIFT, &STM32_SDRAM_FMC->sdtr1); writel(FMC_SDCMR_BANK_1 | FMC_SDCMR_MODE_START_CLOCK, @@ -110,7 +85,7 @@ int stm32_sdram_init(struct udevice *dev) FMC_BUSY_WAIT(); writel(FMC_SDCMR_BANK_1 | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT - | SDRAM_MODE_CAS << SDRAM_MODE_CAS_SHIFT) + | params->sdram_control.cas_latency << SDRAM_MODE_CAS_SHIFT) << FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE, &STM32_SDRAM_FMC->sdcmr); udelay(100); @@ -121,7 +96,7 @@ int stm32_sdram_init(struct udevice *dev) FMC_BUSY_WAIT(); /* Refresh timer */ - writel(SDRAM_TREF, &STM32_SDRAM_FMC->sdrtr); + writel((params->sdram_ref_count) << 1, &STM32_SDRAM_FMC->sdrtr); return 0; } @@ -142,12 +117,14 @@ static int stm32_fmc_ofdata_to_platdata(struct udevice *dev) sizeof(params->sdram_control)); if (ret) return ret; - ret = fdtdec_get_byte_array(blob, node, "st,sdram-timing", (u8 *)¶ms->sdram_timing, sizeof(params->sdram_timing)); if (ret) return ret; + + params->sdram_ref_count = fdtdec_get_int(blob, node, + "st,sdram-refcount", 8196); } return 0; diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h index 73a316d8066..cc0f8fdf921 100644 --- a/include/configs/stm32f746-disco.h +++ b/include/configs/stm32f746-disco.h @@ -16,7 +16,6 @@ * Configuration of the external SDRAM memory */ #define CONFIG_NR_DRAM_BANKS 1 -#define CONFIG_SYS_RAM_FREQ_DIV 2 #define CONFIG_SYS_LOAD_ADDR 0xC0400000 #define CONFIG_LOADADDR 0xC0400000 diff --git a/include/dt-bindings/memory/stm32-sdram.h b/include/dt-bindings/memory/stm32-sdram.h index 4cd6c2b77cb..89b719af534 100644 --- a/include/dt-bindings/memory/stm32-sdram.h +++ b/include/dt-bindings/memory/stm32-sdram.h @@ -18,17 +18,20 @@ #define CAS_1 0x1 #define CAS_2 0x2 #define CAS_3 0x3 +#define SDCLK_2 0x2 #define RD_BURST_EN 0x1 #define RD_BURST_DIS 0x0 #define RD_PIPE_DL_0 0x0 #define RD_PIPE_DL_1 0x1 #define RD_PIPE_DL_2 0x2 -#define TMRD_1 0x1 -#define TXSR_60 60 -#define TRAS_42 42 -#define TRC_60 60 -#define TRP_18 18 -#define TRCD_18 18 +/* Timing = value +1 cycles */ +#define TMRD_2 (2 - 1) +#define TXSR_6 (6 - 1) +#define TRAS_4 (4 - 1) +#define TRC_6 (6 - 1) +#define TWR_2 (2 - 1) +#define TRP_2 (2 - 1) +#define TRCD_2 (2 - 1) #endif -- cgit v1.3.1 From 58fb3c8d89872f82a03c03625dcf5cc61b733bab Mon Sep 17 00:00:00 2001 From: Vikas Manocha Date: Mon, 10 Apr 2017 15:03:04 -0700 Subject: stm32f7: increase the max no of pin configuration to 70 The number of pins to be configured could be more than 50 e.g. in case of sdram controller, there are about 56 pins (32 data lines, 12 address & some control signals). Signed-off-by: Vikas Manocha cc: Christophe KERELLO --- drivers/pinctrl/pinctrl_stm32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 01f0429a399..d7b5ea3e1c0 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -7,6 +7,7 @@ DECLARE_GLOBAL_DATA_PTR; +#define MAX_PINS_ONE_IP 70 #define MODE_BITS_MASK 3 #define OSPEED_MASK 3 #define PUPD_MASK 3 @@ -95,7 +96,7 @@ static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn, int node) static int stm32_pinctrl_set_state_simple(struct udevice *dev, struct udevice *periph) { - u32 pin_mux[50]; + u32 pin_mux[MAX_PINS_ONE_IP]; struct fdtdec_phandle_args args; int rv, len; -- cgit v1.3.1 From 18cae43b62cce86becf84b75829b307fefff54c2 Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Sun, 16 Apr 2017 15:31:59 +0200 Subject: mtd: nand: Consolidate nand spl loaders implementation nand_spl_load_image implementation was copied over into three different drivers and now with nand_spl_read_block used for ubispl situation gets even worse. For now use least intrusive solution and #include the same implementation to nand drivers. Signed-off-by: Ladislav Michl Tested-by: Pau Pajuelo --- drivers/mtd/nand/am335x_spl_bch.c | 49 +---------------- drivers/mtd/nand/atmel_nand.c | 30 +---------- drivers/mtd/nand/nand_spl_loaders.c | 104 ++++++++++++++++++++++++++++++++++++ drivers/mtd/nand/nand_spl_simple.c | 98 +-------------------------------- 4 files changed, 110 insertions(+), 171 deletions(-) create mode 100644 drivers/mtd/nand/nand_spl_loaders.c (limited to 'drivers') diff --git a/drivers/mtd/nand/am335x_spl_bch.c b/drivers/mtd/nand/am335x_spl_bch.c index 5b189a1d8a5..e68b4a5b196 100644 --- a/drivers/mtd/nand/am335x_spl_bch.c +++ b/drivers/mtd/nand/am335x_spl_bch.c @@ -198,53 +198,6 @@ static int nand_read_page(int block, int page, void *dst) return 0; } -int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) -{ - unsigned int block, lastblock; - unsigned int page, page_offset; - - /* - * offs has to be aligned to a page address! - */ - block = offs / CONFIG_SYS_NAND_BLOCK_SIZE; - lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE; - page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE; - page_offset = offs % CONFIG_SYS_NAND_PAGE_SIZE; - - while (block <= lastblock) { - if (!nand_is_bad_block(block)) { - /* - * Skip bad blocks - */ - while (page < CONFIG_SYS_NAND_PAGE_COUNT) { - nand_read_page(block, page, dst); - /* - * When offs is not aligned to page address the - * extra offset is copied to dst as well. Copy - * the image such that its first byte will be - * at the dst. - */ - if (unlikely(page_offset)) { - memmove(dst, dst + page_offset, - CONFIG_SYS_NAND_PAGE_SIZE); - dst = (void *)((int)dst - page_offset); - page_offset = 0; - } - dst += CONFIG_SYS_NAND_PAGE_SIZE; - page++; - } - - page = 0; - } else { - lastblock++; - } - - block++; - } - - return 0; -} - /* nand_init() - initialize data to make nand usable by SPL */ void nand_init(void) { @@ -269,3 +222,5 @@ void nand_deselect(void) if (nand_chip.select_chip) nand_chip.select_chip(mtd, -1); } + +#include "nand_spl_loaders.c" diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 21d5d0e70d0..7c10bfedc6d 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1380,34 +1380,6 @@ static int nand_read_page(int block, int page, void *dst) } #endif /* CONFIG_SPL_NAND_ECC */ -int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) -{ - unsigned int block, lastblock; - unsigned int page; - - block = offs / CONFIG_SYS_NAND_BLOCK_SIZE; - lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE; - page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE; - - while (block <= lastblock) { - if (!nand_is_bad_block(block)) { - while (page < CONFIG_SYS_NAND_PAGE_COUNT) { - nand_read_page(block, page, dst); - dst += CONFIG_SYS_NAND_PAGE_SIZE; - page++; - } - - page = 0; - } else { - lastblock++; - } - - block++; - } - - return 0; -} - int at91_nand_wait_ready(struct mtd_info *mtd) { struct nand_chip *this = mtd_to_nand(mtd); @@ -1474,6 +1446,8 @@ void nand_deselect(void) nand_chip.select_chip(mtd, -1); } +#include "nand_spl_loaders.c" + #else #ifndef CONFIG_SYS_NAND_BASE_LIST diff --git a/drivers/mtd/nand/nand_spl_loaders.c b/drivers/mtd/nand/nand_spl_loaders.c new file mode 100644 index 00000000000..177c12b5815 --- /dev/null +++ b/drivers/mtd/nand/nand_spl_loaders.c @@ -0,0 +1,104 @@ +int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) +{ + unsigned int block, lastblock; + unsigned int page, page_offset; + + /* offs has to be aligned to a page address! */ + block = offs / CONFIG_SYS_NAND_BLOCK_SIZE; + lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE; + page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE; + page_offset = offs % CONFIG_SYS_NAND_PAGE_SIZE; + + while (block <= lastblock) { + if (!nand_is_bad_block(block)) { + /* Skip bad blocks */ + while (page < CONFIG_SYS_NAND_PAGE_COUNT) { + nand_read_page(block, page, dst); + /* + * When offs is not aligned to page address the + * extra offset is copied to dst as well. Copy + * the image such that its first byte will be + * at the dst. + */ + if (unlikely(page_offset)) { + memmove(dst, dst + page_offset, + CONFIG_SYS_NAND_PAGE_SIZE); + dst = (void *)((int)dst - page_offset); + page_offset = 0; + } + dst += CONFIG_SYS_NAND_PAGE_SIZE; + page++; + } + + page = 0; + } else { + lastblock++; + } + + block++; + } + + return 0; +} + +#ifdef CONFIG_SPL_UBI +/* + * Temporary storage for non NAND page aligned and non NAND page sized + * reads. Note: This does not support runtime detected FLASH yet, but + * that should be reasonably easy to fix by making the buffer large + * enough :) + */ +static u8 scratch_buf[CONFIG_SYS_NAND_PAGE_SIZE]; + +/** + * nand_spl_read_block - Read data from physical eraseblock into a buffer + * @block: Number of the physical eraseblock + * @offset: Data offset from the start of @peb + * @len: Data size to read + * @dst: Address of the destination buffer + * + * This could be further optimized if we'd have a subpage read + * function in the simple code. On NAND which allows subpage reads + * this would spare quite some time to readout e.g. the VID header of + * UBI. + * + * Notes: + * @offset + @len are not allowed to be larger than a physical + * erase block. No sanity check done for simplicity reasons. + * + * To support runtime detected flash this needs to be extended by + * information about the actual flash geometry, but thats beyond the + * scope of this effort and for most applications where fast boot is + * required it is not an issue anyway. + */ +int nand_spl_read_block(int block, int offset, int len, void *dst) +{ + int page, read; + + /* Calculate the page number */ + page = offset / CONFIG_SYS_NAND_PAGE_SIZE; + + /* Offset to the start of a flash page */ + offset = offset % CONFIG_SYS_NAND_PAGE_SIZE; + + while (len) { + /* + * Non page aligned reads go to the scratch buffer. + * Page aligned reads go directly to the destination. + */ + if (offset || len < CONFIG_SYS_NAND_PAGE_SIZE) { + nand_read_page(block, page, scratch_buf); + read = min(len, CONFIG_SYS_NAND_PAGE_SIZE - offset); + memcpy(dst, scratch_buf + offset, read); + offset = 0; + } else { + nand_read_page(block, page, dst); + read = CONFIG_SYS_NAND_PAGE_SIZE; + } + page++; + len -= read; + dst += read; + } + return 0; +} +#endif diff --git a/drivers/mtd/nand/nand_spl_simple.c b/drivers/mtd/nand/nand_spl_simple.c index 55f48d3a142..56e86d17609 100644 --- a/drivers/mtd/nand/nand_spl_simple.c +++ b/drivers/mtd/nand/nand_spl_simple.c @@ -209,102 +209,6 @@ static int nand_read_page(int block, int page, void *dst) } #endif -#ifdef CONFIG_SPL_UBI -/* - * Temporary storage for non NAND page aligned and non NAND page sized - * reads. Note: This does not support runtime detected FLASH yet, but - * that should be reasonably easy to fix by making the buffer large - * enough :) - */ -static u8 scratch_buf[CONFIG_SYS_NAND_PAGE_SIZE]; - -/** - * nand_spl_read_block - Read data from physical eraseblock into a buffer - * @block: Number of the physical eraseblock - * @offset: Data offset from the start of @peb - * @len: Data size to read - * @dst: Address of the destination buffer - * - * This could be further optimized if we'd have a subpage read - * function in the simple code. On NAND which allows subpage reads - * this would spare quite some time to readout e.g. the VID header of - * UBI. - * - * Notes: - * @offset + @len are not allowed to be larger than a physical - * erase block. No sanity check done for simplicity reasons. - * - * To support runtime detected flash this needs to be extended by - * information about the actual flash geometry, but thats beyond the - * scope of this effort and for most applications where fast boot is - * required it is not an issue anyway. - */ -int nand_spl_read_block(int block, int offset, int len, void *dst) -{ - int page, read; - - /* Calculate the page number */ - page = offset / CONFIG_SYS_NAND_PAGE_SIZE; - - /* Offset to the start of a flash page */ - offset = offset % CONFIG_SYS_NAND_PAGE_SIZE; - - while (len) { - /* - * Non page aligned reads go to the scratch buffer. - * Page aligned reads go directly to the destination. - */ - if (offset || len < CONFIG_SYS_NAND_PAGE_SIZE) { - nand_read_page(block, page, scratch_buf); - read = min(len, CONFIG_SYS_NAND_PAGE_SIZE - offset); - memcpy(dst, scratch_buf + offset, read); - offset = 0; - } else { - nand_read_page(block, page, dst); - read = CONFIG_SYS_NAND_PAGE_SIZE; - } - page++; - len -= read; - dst += read; - } - return 0; -} -#endif - -int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) -{ - unsigned int block, lastblock; - unsigned int page; - - /* - * offs has to be aligned to a page address! - */ - block = offs / CONFIG_SYS_NAND_BLOCK_SIZE; - lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE; - page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE; - - while (block <= lastblock) { - if (!nand_is_bad_block(block)) { - /* - * Skip bad blocks - */ - while (page < CONFIG_SYS_NAND_PAGE_COUNT) { - nand_read_page(block, page, dst); - dst += CONFIG_SYS_NAND_PAGE_SIZE; - page++; - } - - page = 0; - } else { - lastblock++; - } - - block++; - } - - return 0; -} - /* nand_init() - initialize data to make nand usable by SPL */ void nand_init(void) { @@ -333,3 +237,5 @@ void nand_deselect(void) if (nand_chip.select_chip) nand_chip.select_chip(mtd, -1); } + +#include "nand_spl_loaders.c" -- cgit v1.3.1 From d425d6056e0159ee26cb7f7037ff0b72ffd93658 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Sat, 29 Apr 2017 15:20:29 +1200 Subject: rtc: Add DM support to ds1307 Add an implementation of the ds1307 driver that uses the driver model i2c APIs. Signed-off-by: Chris Packham Reviewed-by: Simon Glass --- drivers/rtc/Kconfig | 7 ++ drivers/rtc/ds1307.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 196 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index cb79a016316..d06130c7a2e 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -23,4 +23,11 @@ config RTC_PCF2127 has a selectable I2C-bus or SPI-bus, a backup battery switch-over circuit, a programmable watchdog function, a timestamp function, and many other features. +config RTC_DS1307 + bool "Enable DS1307 driver" + depends on DM_RTC + help + Support for Dallas Semiconductor (now Maxim) DS1307 and DS1338/9 and + compatible Real Time Clock devices. + endmenu diff --git a/drivers/rtc/ds1307.c b/drivers/rtc/ds1307.c index 3be1da68731..5df15c7fd6c 100644 --- a/drivers/rtc/ds1307.c +++ b/drivers/rtc/ds1307.c @@ -16,28 +16,16 @@ #include #include +#include #include #include -#if defined(CONFIG_CMD_DATE) - -/*---------------------------------------------------------------------*/ -#undef DEBUG_RTC - -#ifdef DEBUG_RTC -#define DEBUGR(fmt,args...) printf(fmt ,##args) -#else -#define DEBUGR(fmt,args...) -#endif -/*---------------------------------------------------------------------*/ - -#ifndef CONFIG_SYS_I2C_RTC_ADDR -# define CONFIG_SYS_I2C_RTC_ADDR 0x68 -#endif - -#if defined(CONFIG_RTC_DS1307) && (CONFIG_SYS_I2C_SPEED > 100000) -# error The DS1307 is specified only up to 100kHz! -#endif +enum ds_type { + ds_1307, + ds_1337, + ds_1340, + mcp794xx, +}; /* * RTC register addresses @@ -62,6 +50,28 @@ #define MCP7941X_BIT_ST 0x80 #define MCP7941X_BIT_VBATEN 0x08 +#ifndef CONFIG_DM_RTC + +#if defined(CONFIG_CMD_DATE) + +/*---------------------------------------------------------------------*/ +#undef DEBUG_RTC + +#ifdef DEBUG_RTC +#define DEBUGR(fmt, args...) printf(fmt, ##args) +#else +#define DEBUGR(fmt, args...) +#endif +/*---------------------------------------------------------------------*/ + +#ifndef CONFIG_SYS_I2C_RTC_ADDR +# define CONFIG_SYS_I2C_RTC_ADDR 0x68 +#endif + +#if defined(CONFIG_RTC_DS1307) && (CONFIG_SYS_I2C_SPEED > 100000) +# error The DS1307 is specified only up to 100kHz! +#endif + static uchar rtc_read (uchar reg); static void rtc_write (uchar reg, uchar val); @@ -211,4 +221,163 @@ static void rtc_write (uchar reg, uchar val) { i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val); } -#endif + +#endif /* CONFIG_CMD_DATE*/ + +#endif /* !CONFIG_DM_RTC */ + +#ifdef CONFIG_DM_RTC +static int ds1307_rtc_set(struct udevice *dev, const struct rtc_time *tm) +{ + int ret; + uchar buf[7]; + enum ds_type type = dev_get_driver_data(dev); + + debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + + if (tm->tm_year < 1970 || tm->tm_year > 2069) + printf("WARNING: year should be between 1970 and 2069!\n"); + + buf[RTC_YR_REG_ADDR] = bin2bcd(tm->tm_year % 100); + buf[RTC_MON_REG_ADDR] = bin2bcd(tm->tm_mon); + buf[RTC_DAY_REG_ADDR] = bin2bcd(tm->tm_wday + 1); + buf[RTC_DATE_REG_ADDR] = bin2bcd(tm->tm_mday); + buf[RTC_HR_REG_ADDR] = bin2bcd(tm->tm_hour); + buf[RTC_MIN_REG_ADDR] = bin2bcd(tm->tm_min); + buf[RTC_SEC_REG_ADDR] = bin2bcd(tm->tm_sec); + + if (type == mcp794xx) { + buf[RTC_DAY_REG_ADDR] |= MCP7941X_BIT_VBATEN; + buf[RTC_SEC_REG_ADDR] |= MCP7941X_BIT_ST; + } + + ret = dm_i2c_write(dev, 0, buf, sizeof(buf)); + if (ret < 0) + return ret; + + return 0; +} + +static int ds1307_rtc_get(struct udevice *dev, struct rtc_time *tm) +{ + int ret; + uchar buf[7]; + enum ds_type type = dev_get_driver_data(dev); + +read_rtc: + ret = dm_i2c_read(dev, 0, buf, sizeof(buf)); + if (ret < 0) + return ret; + + if (type == ds_1307) { + if (buf[RTC_SEC_REG_ADDR] & RTC_SEC_BIT_CH) { + printf("### Warning: RTC oscillator has stopped\n"); + /* clear the CH flag */ + buf[RTC_SEC_REG_ADDR] &= ~RTC_SEC_BIT_CH; + dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR, + buf[RTC_SEC_REG_ADDR]); + return -1; + } + } + + if (type == mcp794xx) { + /* make sure that the backup battery is enabled */ + if (!(buf[RTC_DAY_REG_ADDR] & MCP7941X_BIT_VBATEN)) { + dm_i2c_reg_write(dev, RTC_DAY_REG_ADDR, + buf[RTC_DAY_REG_ADDR] | + MCP7941X_BIT_VBATEN); + } + + /* clock halted? turn it on, so clock can tick. */ + if (!(buf[RTC_SEC_REG_ADDR] & MCP7941X_BIT_ST)) { + dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR, + MCP7941X_BIT_ST); + printf("Started RTC\n"); + goto read_rtc; + } + } + + tm->tm_sec = bcd2bin(buf[RTC_SEC_REG_ADDR] & 0x7F); + tm->tm_min = bcd2bin(buf[RTC_MIN_REG_ADDR] & 0x7F); + tm->tm_hour = bcd2bin(buf[RTC_HR_REG_ADDR] & 0x3F); + tm->tm_mday = bcd2bin(buf[RTC_DATE_REG_ADDR] & 0x3F); + tm->tm_mon = bcd2bin(buf[RTC_MON_REG_ADDR] & 0x1F); + tm->tm_year = bcd2bin(buf[RTC_YR_REG_ADDR]) + + (bcd2bin(buf[RTC_YR_REG_ADDR]) >= 70 ? + 1900 : 2000); + tm->tm_wday = bcd2bin((buf[RTC_DAY_REG_ADDR] - 1) & 0x07); + tm->tm_yday = 0; + tm->tm_isdst = 0; + + debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + + return 0; +} + +static int ds1307_rtc_reset(struct udevice *dev) +{ + int ret; + struct rtc_time tmp = { + .tm_year = 1970, + .tm_mon = 1, + .tm_mday = 1, + .tm_hour = 0, + .tm_min = 0, + .tm_sec = 0, + }; + + /* clear Clock Halt */ + ret = dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR, 0x00); + if (ret < 0) + return ret; + ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR, + RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 | + RTC_CTL_BIT_RS0); + if (ret < 0) + return ret; + + ret = ds1307_rtc_set(dev, &tmp); + if (ret < 0) + return ret; + + debug("RTC: %4d-%02d-%02d %2d:%02d:%02d UTC\n", + tmp.tm_year, tmp.tm_mon, tmp.tm_mday, + tmp.tm_hour, tmp.tm_min, tmp.tm_sec); + + return 0; +} + +static int ds1307_probe(struct udevice *dev) +{ + i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS | + DM_I2C_CHIP_WR_ADDRESS); + + return 0; +} + +static const struct rtc_ops ds1307_rtc_ops = { + .get = ds1307_rtc_get, + .set = ds1307_rtc_set, + .reset = ds1307_rtc_reset, +}; + +static const struct udevice_id ds1307_rtc_ids[] = { + { .compatible = "dallas,ds1307", .data = ds_1307 }, + { .compatible = "dallas,ds1337", .data = ds_1337 }, + { .compatible = "dallas,ds1340", .data = ds_1340 }, + { .compatible = "microchip,mcp7941x", .data = mcp794xx }, + { } +}; + +U_BOOT_DRIVER(rtc_ds1307) = { + .name = "rtc-ds1307", + .id = UCLASS_RTC, + .probe = ds1307_probe, + .of_match = ds1307_rtc_ids, + .ops = &ds1307_rtc_ops, +}; +#endif /* CONFIG_DM_RTC */ -- cgit v1.3.1 From 0753bc2d30d7ca4a0ea4ef7f97083961c3a9d0e0 Mon Sep 17 00:00:00 2001 From: "maxims@google.com" Date: Mon, 17 Apr 2017 12:00:21 -0700 Subject: dm: Simple Watchdog uclass This is a simple uclass for Watchdog Timers. It has four operations: start, restart, reset, stop. Drivers must implement start, restart and stop operations, while implementing reset is optional: It's default implementation expires watchdog timer in one clock tick. Signed-off-by: Maxim Sloyko Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 4 ++ arch/sandbox/include/asm/state.h | 9 ++++ configs/sandbox_defconfig | 2 + drivers/watchdog/Kconfig | 20 +++++++- drivers/watchdog/Makefile | 2 + drivers/watchdog/sandbox_wdt.c | 76 +++++++++++++++++++++++++++ drivers/watchdog/wdt-uclass.c | 72 ++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/wdt.h | 107 +++++++++++++++++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/wdt.c | 40 +++++++++++++++ 11 files changed, 333 insertions(+), 1 deletion(-) create mode 100644 drivers/watchdog/sandbox_wdt.c create mode 100644 drivers/watchdog/wdt-uclass.c create mode 100644 include/wdt.h create mode 100644 test/dm/wdt.c (limited to 'drivers') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 50bcdebf74d..094c5aaf61a 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -426,6 +426,10 @@ }; }; }; + + wdt0: wdt@0 { + compatible = "sandbox,wdt"; + }; }; #include "sandbox_pmic.dtsi" diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 149f28d8732..987cc7b49dc 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -39,6 +39,12 @@ struct sandbox_spi_info { struct udevice *emul; }; +struct sandbox_wdt_info { + unsigned long long counter; + uint reset_count; + bool running; +}; + /* The complete state of the test system */ struct sandbox_state { const char *cmd; /* Command to execute */ @@ -69,6 +75,9 @@ struct sandbox_state { /* Pointer to information for each SPI bus/cs */ struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS] [CONFIG_SANDBOX_SPI_MAX_CS]; + + /* Information about Watchdog */ + struct sandbox_wdt_info wdt; }; /* Minimum space we guarantee in the state FDT when calling read/write*/ diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index d3fee89f48c..64bb923c13a 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -180,3 +180,5 @@ CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y CONFIG_UT_ENV=y +CONFIG_WDT=y +CONFIG_WDT_SANDBOX=y diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index dbdaafc1498..e8d2dba835c 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1,8 +1,26 @@ -menu "WATCHDOG support" +menu "Watchdog Timer Support" config ULP_WATCHDOG bool "i.MX7ULP watchdog" help Say Y here to enable i.MX7ULP watchdog driver. +config WDT + bool "Enable driver model for watchdog timer drivers" + depends on DM + help + Enable driver model for watchdog timer. At the moment the API + is very simple and only supports four operations: + start, restart, stop and reset (expire immediately). + What exactly happens when the timer expires is up to a particular + device/driver. + +config WDT_SANDBOX + bool "Enable Watchdog Timer support for Sandbox" + depends on SANDBOX && WDT + help + Enable Watchdog Timer support in Sandbox. This is a dummy device that + can be probed and supports all of the methods of WDT, but does not + really do anything. + endmenu diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 36745ca9c99..e891d648496 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -15,3 +15,5 @@ obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o +obj-$(CONFIG_WDT) += wdt-uclass.o +obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o diff --git a/drivers/watchdog/sandbox_wdt.c b/drivers/watchdog/sandbox_wdt.c new file mode 100644 index 00000000000..34d90bee7e8 --- /dev/null +++ b/drivers/watchdog/sandbox_wdt.c @@ -0,0 +1,76 @@ +/* + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static int sandbox_wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{ + struct sandbox_state *state = state_get_current(); + + state->wdt.counter = timeout; + state->wdt.running = true; + + return 0; +} + +static int sandbox_wdt_stop(struct udevice *dev) +{ + struct sandbox_state *state = state_get_current(); + + state->wdt.running = false; + + return 0; +} + +static int sandbox_wdt_reset(struct udevice *dev) +{ + struct sandbox_state *state = state_get_current(); + + state->wdt.reset_count++; + + return 0; +} + +static int sandbox_wdt_expire_now(struct udevice *dev, ulong flags) +{ + sandbox_wdt_start(dev, 1, flags); + + return 0; +} + +static int sandbox_wdt_probe(struct udevice *dev) +{ + struct sandbox_state *state = state_get_current(); + + memset(&state->wdt, 0, sizeof(state->wdt)); + + return 0; +} + +static const struct wdt_ops sandbox_wdt_ops = { + .start = sandbox_wdt_start, + .reset = sandbox_wdt_reset, + .stop = sandbox_wdt_stop, + .expire_now = sandbox_wdt_expire_now, +}; + +static const struct udevice_id sandbox_wdt_ids[] = { + { .compatible = "sandbox,wdt" }, + {} +}; + +U_BOOT_DRIVER(wdt_sandbox) = { + .name = "wdt_sandbox", + .id = UCLASS_WDT, + .of_match = sandbox_wdt_ids, + .ops = &sandbox_wdt_ops, + .probe = sandbox_wdt_probe, +}; diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c new file mode 100644 index 00000000000..ab8a64c354a --- /dev/null +++ b/drivers/watchdog/wdt-uclass.c @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{ + const struct wdt_ops *ops = device_get_ops(dev); + + if (!ops->start) + return -ENOSYS; + + return ops->start(dev, timeout, flags); +} + +int wdt_stop(struct udevice *dev) +{ + const struct wdt_ops *ops = device_get_ops(dev); + + if (!ops->stop) + return -ENOSYS; + + return ops->stop(dev); +} + +int wdt_reset(struct udevice *dev) +{ + const struct wdt_ops *ops = device_get_ops(dev); + + if (!ops->reset) + return -ENOSYS; + + return ops->reset(dev); +} + +int wdt_expire_now(struct udevice *dev, ulong flags) +{ + int ret = 0; + const struct wdt_ops *ops; + + debug("WDT Resettting: %lu\n", flags); + ops = device_get_ops(dev); + if (ops->expire_now) { + return ops->expire_now(dev, flags); + } else { + if (!ops->start) + return -ENOSYS; + + ret = ops->start(dev, 1, flags); + if (ret < 0) + return ret; + + hang(); + } + + return ret; +} + +UCLASS_DRIVER(wdt) = { + .id = UCLASS_WDT, + .name = "wdt", +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 1b635e41103..4e7cc935bd2 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -84,6 +84,7 @@ enum uclass_id { UCLASS_VIDEO, /* Video or LCD device */ UCLASS_VIDEO_BRIDGE, /* Video bridge, e.g. DisplayPort to LVDS */ UCLASS_VIDEO_CONSOLE, /* Text console driver for video device */ + UCLASS_WDT, /* Watchdot Timer driver */ UCLASS_COUNT, UCLASS_INVALID = -1, diff --git a/include/wdt.h b/include/wdt.h new file mode 100644 index 00000000000..0b5f05851a3 --- /dev/null +++ b/include/wdt.h @@ -0,0 +1,107 @@ +/* + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _WDT_H_ +#define _WDT_H_ + +/* + * Implement a simple watchdog uclass. Watchdog is basically a timer that + * is used to detect or recover from malfunction. During normal operation + * the watchdog would be regularly reset to prevent it from timing out. + * If, due to a hardware fault or program error, the computer fails to reset + * the watchdog, the timer will elapse and generate a timeout signal. + * The timeout signal is used to initiate corrective action or actions, + * which typically include placing the system in a safe, known state. + */ + +/* + * Start the timer + * + * @dev: WDT Device + * @timeout: Number of ticks before timer expires + * @flags: Driver specific flags. This might be used to specify + * which action needs to be executed when the timer expires + * @return: 0 if OK, -ve on error + */ +int wdt_start(struct udevice *dev, u64 timeout, ulong flags); + +/* + * Stop the timer, thus disabling the Watchdog. Use wdt_start to start it again. + * + * @dev: WDT Device + * @return: 0 if OK, -ve on error + */ +int wdt_stop(struct udevice *dev); + +/* + * Reset the timer, typically restoring the counter to + * the value configured by start() + * + * @dev: WDT Device + * @return: 0 if OK, -ve on error + */ +int wdt_reset(struct udevice *dev); + +/* + * Expire the timer, thus executing its action immediately. + * This is typically used to reset the board or peripherals. + * + * @dev: WDT Device + * @flags: Driver specific flags + * @return 0 if OK -ve on error. If wdt action is system reset, + * this function may never return. + */ +int wdt_expire_now(struct udevice *dev, ulong flags); + +/* + * struct wdt_ops - Driver model wdt operations + * + * The uclass interface is implemented by all wdt devices which use + * driver model. + */ +struct wdt_ops { + /* + * Start the timer + * + * @dev: WDT Device + * @timeout: Number of ticks before the timer expires + * @flags: Driver specific flags. This might be used to specify + * which action needs to be executed when the timer expires + * @return: 0 if OK, -ve on error + */ + int (*start)(struct udevice *dev, u64 timeout, ulong flags); + /* + * Stop the timer + * + * @dev: WDT Device + * @return: 0 if OK, -ve on error + */ + int (*stop)(struct udevice *dev); + /* + * Reset the timer, typically restoring the counter to + * the value configured by start() + * + * @dev: WDT Device + * @return: 0 if OK, -ve on error + */ + int (*reset)(struct udevice *dev); + /* + * Expire the timer, thus executing the action immediately (optional) + * + * If this function is not provided, a default implementation + * will be used, which sets the counter to 1 + * and waits forever. This is good enough for system level + * reset, where the function is not expected to return, but might not be + * good enough for other use cases. + * + * @dev: WDT Device + * @flags: Driver specific flags + * @return 0 if OK -ve on error. May not return. + */ + int (*expire_now)(struct udevice *dev, ulong flags); +}; + +#endif /* _WDT_H_ */ diff --git a/test/dm/Makefile b/test/dm/Makefile index e956915bc3d..b15f1d0535a 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -42,4 +42,5 @@ obj-$(CONFIG_TIMER) += timer.o obj-$(CONFIG_DM_VIDEO) += video.o obj-$(CONFIG_ADC) += adc.o obj-$(CONFIG_SPMI) += spmi.o +obj-$(CONFIG_WDT) += wdt.o endif diff --git a/test/dm/wdt.c b/test/dm/wdt.c new file mode 100644 index 00000000000..2ecfceaaff9 --- /dev/null +++ b/test/dm/wdt.c @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Test that watchdog driver functions are called */ +static int dm_test_wdt_base(struct unit_test_state *uts) +{ + struct sandbox_state *state = state_get_current(); + struct udevice *dev; + const u64 timeout = 42; + + ut_assertok(uclass_get_device(UCLASS_WDT, 0, &dev)); + ut_asserteq(0, state->wdt.counter); + ut_asserteq(false, state->wdt.running); + + ut_assertok(wdt_start(dev, timeout, 0)); + ut_asserteq(timeout, state->wdt.counter); + ut_asserteq(true, state->wdt.running); + + uint reset_count = state->wdt.reset_count; + ut_assertok(wdt_reset(dev)); + ut_asserteq(reset_count + 1, state->wdt.reset_count); + ut_asserteq(true, state->wdt.running); + + ut_assertok(wdt_stop(dev)); + ut_asserteq(false, state->wdt.running); + + return 0; +} +DM_TEST(dm_test_wdt_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit v1.3.1 From 1eb0a464b7434175800c98a175909588d38c1dae Mon Sep 17 00:00:00 2001 From: "maxims@google.com" Date: Mon, 17 Apr 2017 12:00:22 -0700 Subject: aspeed: Watchdog Timer Driver This driver supports ast2500 and ast2400 SoCs. Only ast2500 supports reset_mask and thus the option of resettting individual peripherals using WDT. Signed-off-by: Maxim Sloyko Reviewed-by: Simon Glass --- arch/arm/include/asm/arch-aspeed/wdt.h | 53 ++++++++++++-- arch/arm/mach-aspeed/ast_wdt.c | 40 ++++++++--- drivers/watchdog/Kconfig | 11 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/ast_wdt.c | 125 +++++++++++++++++++++++++++++++++ 5 files changed, 217 insertions(+), 13 deletions(-) create mode 100644 drivers/watchdog/ast_wdt.c (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h index b292a0e67b5..981fa05a567 100644 --- a/arch/arm/include/asm/arch-aspeed/wdt.h +++ b/arch/arm/include/asm/arch-aspeed/wdt.h @@ -67,15 +67,60 @@ struct ast_wdt { u32 timeout_status; u32 clr_timeout_status; u32 reset_width; -#ifdef CONFIG_ASPEED_AST2500 + /* On pre-ast2500 SoCs this register is reserved. */ u32 reset_mask; -#else - u32 reserved0; -#endif }; +/** + * Given flags parameter passed to wdt_reset or wdt_start uclass functions, + * gets Reset Mode value from it. + * + * @flags: flags parameter passed into wdt_reset or wdt_start + * @return Reset Mode value + */ +u32 ast_reset_mode_from_flags(ulong flags); + +/** + * Given flags parameter passed to wdt_reset or wdt_start uclass functions, + * gets Reset Mask value from it. Reset Mask is only supported on ast2500 + * + * @flags: flags parameter passed into wdt_reset or wdt_start + * @return Reset Mask value + */ +u32 ast_reset_mask_from_flags(ulong flags); + +/** + * Given Reset Mask and Reset Mode values, converts them to flags, + * suitable for passing into wdt_start or wdt_reset uclass functions. + * + * On ast2500 Reset Mask is 25 bits wide and Reset Mode is 2 bits wide, so they + * can both be packed into single 32 bits wide value. + * + * @reset_mode: Reset Mode + * @reset_mask: Reset Mask + */ +ulong ast_flags_from_reset_mode_mask(u32 reset_mode, u32 reset_mask); + +#ifndef CONFIG_WDT +/** + * Stop WDT + * + * @wdt: watchdog to stop + * + * When using driver model this function has different signature + */ void wdt_stop(struct ast_wdt *wdt); + +/** + * Stop WDT + * + * @wdt: watchdog to start + * @timeout watchdog timeout in number of clock ticks + * + * When using driver model this function has different signature + */ void wdt_start(struct ast_wdt *wdt, u32 timeout); +#endif /* CONFIG_WDT */ /** * Reset peripherals specified by mask diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c index 22481ab7ea1..895fba3366c 100644 --- a/arch/arm/mach-aspeed/ast_wdt.c +++ b/arch/arm/mach-aspeed/ast_wdt.c @@ -9,6 +9,27 @@ #include #include +u32 ast_reset_mode_from_flags(ulong flags) +{ + return flags & WDT_CTRL_RESET_MASK; +} + +u32 ast_reset_mask_from_flags(ulong flags) +{ + return flags >> 2; +} + +ulong ast_flags_from_reset_mode_mask(u32 reset_mode, u32 reset_mask) +{ + ulong ret = reset_mode & WDT_CTRL_RESET_MASK; + + if (ret == WDT_CTRL_RESET_SOC) + ret |= (reset_mask << 2); + + return ret; +} + +#ifndef CONFIG_WDT void wdt_stop(struct ast_wdt *wdt) { clrbits_le32(&wdt->ctrl, WDT_CTRL_EN); @@ -26,15 +47,7 @@ void wdt_start(struct ast_wdt *wdt, u32 timeout) setbits_le32(&wdt->ctrl, WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ); } - -struct ast_wdt *ast_get_wdt(u8 wdt_number) -{ - if (wdt_number > CONFIG_WDT_NUM - 1) - return ERR_PTR(-EINVAL); - - return (struct ast_wdt *)(WDT_BASE + - sizeof(struct ast_wdt) * wdt_number); -} +#endif /* CONFIG_WDT */ int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask) { @@ -57,3 +70,12 @@ int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask) return -EINVAL; #endif } + +struct ast_wdt *ast_get_wdt(u8 wdt_number) +{ + if (wdt_number > CONFIG_WDT_NUM - 1) + return ERR_PTR(-EINVAL); + + return (struct ast_wdt *)(WDT_BASE + + sizeof(struct ast_wdt) * wdt_number); +} diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index e8d2dba835c..2034e3c620f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -23,4 +23,15 @@ config WDT_SANDBOX can be probed and supports all of the methods of WDT, but does not really do anything. +config WDT_ASPEED + bool "Aspeed ast2400/ast2500 watchdog timer support" + depends on WDT + default y if ARCH_ASPEED + help + Select this to enable watchdog timer for Aspeed ast2500/ast2400 devices. + The watchdog timer is stopped when initialized. It performs reset, either + full SoC reset or CPU or just some peripherals, based on the flags. + It currently does not support Boot Flash Addressing Mode Detection or + Second Boot. + endmenu diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index e891d648496..dfc7fbda4ab 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o obj-$(CONFIG_WDT) += wdt-uclass.o obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o +obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o diff --git a/drivers/watchdog/ast_wdt.c b/drivers/watchdog/ast_wdt.c new file mode 100644 index 00000000000..b2bd912ad53 --- /dev/null +++ b/drivers/watchdog/ast_wdt.c @@ -0,0 +1,125 @@ +/* + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +#define WDT_AST2500 2500 +#define WDT_AST2400 2400 + +DECLARE_GLOBAL_DATA_PTR; + +struct ast_wdt_priv { + struct ast_wdt *regs; +}; + +static int ast_wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{ + struct ast_wdt_priv *priv = dev_get_priv(dev); + ulong driver_data = dev_get_driver_data(dev); + u32 reset_mode = ast_reset_mode_from_flags(flags); + + clrsetbits_le32(&priv->regs->ctrl, + WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT, + reset_mode << WDT_CTRL_RESET_MODE_SHIFT); + + if (driver_data >= WDT_AST2500 && reset_mode == WDT_CTRL_RESET_SOC) + writel(ast_reset_mask_from_flags(flags), + &priv->regs->reset_mask); + + writel((u32) timeout, &priv->regs->counter_reload_val); + writel(WDT_COUNTER_RESTART_VAL, &priv->regs->counter_restart); + /* + * Setting CLK1MHZ bit is just for compatibility with ast2400 part. + * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is + * read-only + */ + setbits_le32(&priv->regs->ctrl, + WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ); + + return 0; +} + +static int ast_wdt_stop(struct udevice *dev) +{ + struct ast_wdt_priv *priv = dev_get_priv(dev); + + clrbits_le32(&priv->regs->ctrl, WDT_CTRL_EN); + + return 0; +} + +static int ast_wdt_reset(struct udevice *dev) +{ + struct ast_wdt_priv *priv = dev_get_priv(dev); + + writel(WDT_COUNTER_RESTART_VAL, &priv->regs->counter_restart); + + return 0; +} + +static int ast_wdt_expire_now(struct udevice *dev, ulong flags) +{ + struct ast_wdt_priv *priv = dev_get_priv(dev); + int ret; + + ret = ast_wdt_start(dev, 1, flags); + if (ret) + return ret; + + while (readl(&priv->regs->ctrl) & WDT_CTRL_EN) + ; + + return ast_wdt_stop(dev); +} + +static int ast_wdt_ofdata_to_platdata(struct udevice *dev) +{ + struct ast_wdt_priv *priv = dev_get_priv(dev); + + priv->regs = dev_get_addr_ptr(dev); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + + return 0; +} + +static const struct wdt_ops ast_wdt_ops = { + .start = ast_wdt_start, + .reset = ast_wdt_reset, + .stop = ast_wdt_stop, + .expire_now = ast_wdt_expire_now, +}; + +static const struct udevice_id ast_wdt_ids[] = { + { .compatible = "aspeed,wdt", .data = WDT_AST2500 }, + { .compatible = "aspeed,ast2500-wdt", .data = WDT_AST2500 }, + { .compatible = "aspeed,ast2400-wdt", .data = WDT_AST2400 }, + {} +}; + +static int ast_wdt_probe(struct udevice *dev) +{ + debug("%s() wdt%u\n", __func__, dev->seq); + ast_wdt_stop(dev); + + return 0; +} + +U_BOOT_DRIVER(ast_wdt) = { + .name = "ast_wdt", + .id = UCLASS_WDT, + .of_match = ast_wdt_ids, + .probe = ast_wdt_probe, + .priv_auto_alloc_size = sizeof(struct ast_wdt_priv), + .ofdata_to_platdata = ast_wdt_ofdata_to_platdata, + .ops = &ast_wdt_ops, + .flags = DM_FLAG_PRE_RELOC, +}; -- cgit v1.3.1 From 413353b30b5d23c409b6a2fd70aa1cc28451a451 Mon Sep 17 00:00:00 2001 From: "maxims@google.com" Date: Mon, 17 Apr 2017 12:00:23 -0700 Subject: aspeed: Make SCU lock/unlock functions part of SCU API Make functions for locking and unlocking SCU part of SCU API. Many drivers need to modify settings in SCU and thus need to unlock it first. This change makes it possible. Signed-off-by: Maxim Sloyko Reviewed-by: Simon Glass --- arch/arm/include/asm/arch-aspeed/scu_ast2500.h | 14 ++++++++++++++ arch/arm/mach-aspeed/ast2500/clk_ast2500.c | 15 +++++++++++++++ drivers/clk/aspeed/clk_ast2500.c | 18 ++---------------- 3 files changed, 31 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h index fc0c01ae330..0fa3ecb9b91 100644 --- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h +++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h @@ -120,6 +120,20 @@ int ast_get_clk(struct udevice **devp); */ void *ast_get_scu(void); +/** + * ast_scu_unlock() - unlock protected registers + * + * @scu, pointer to ast2500_scu + */ +void ast_scu_unlock(struct ast2500_scu *scu); + +/** + * ast_scu_lock() - lock protected registers + * + * @scu, pointer to ast2500_scu + */ +void ast_scu_lock(struct ast2500_scu *scu); + #endif /* __ASSEMBLY__ */ #endif /* _ASM_ARCH_SCU_AST2500_H */ diff --git a/arch/arm/mach-aspeed/ast2500/clk_ast2500.c b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c index 079909fa646..30cfac1af0f 100644 --- a/arch/arm/mach-aspeed/ast2500/clk_ast2500.c +++ b/arch/arm/mach-aspeed/ast2500/clk_ast2500.c @@ -6,6 +6,7 @@ #include #include +#include #include int ast_get_clk(struct udevice **devp) @@ -28,3 +29,17 @@ void *ast_get_scu(void) return priv->scu; } + +void ast_scu_unlock(struct ast2500_scu *scu) +{ + writel(SCU_UNLOCK_VALUE, &scu->protection_key); + while (!readl(&scu->protection_key)) + ; +} + +void ast_scu_lock(struct ast2500_scu *scu) +{ + writel(~SCU_UNLOCK_VALUE, &scu->protection_key); + while (readl(&scu->protection_key)) + ; +} diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c index 26a5e58221c..504731271c3 100644 --- a/drivers/clk/aspeed/clk_ast2500.c +++ b/drivers/clk/aspeed/clk_ast2500.c @@ -132,20 +132,6 @@ static ulong ast2500_clk_get_rate(struct clk *clk) return rate; } -static void ast2500_scu_unlock(struct ast2500_scu *scu) -{ - writel(SCU_UNLOCK_VALUE, &scu->protection_key); - while (!readl(&scu->protection_key)) - ; -} - -static void ast2500_scu_lock(struct ast2500_scu *scu) -{ - writel(~SCU_UNLOCK_VALUE, &scu->protection_key); - while (readl(&scu->protection_key)) - ; -} - static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate) { ulong clkin = ast2500_get_clkin(scu); @@ -197,9 +183,9 @@ static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate) | (best_num << SCU_MPLL_NUM_SHIFT) | (best_denum << SCU_MPLL_DENUM_SHIFT); - ast2500_scu_unlock(scu); + ast_scu_unlock(scu); writel(mpll_reg, &scu->m_pll_param); - ast2500_scu_lock(scu); + ast_scu_lock(scu); return ast2500_get_mpll_rate(clkin, mpll_reg); } -- cgit v1.3.1 From 858d4976293f0b3d72e5dcf0e8a1a973efafeee3 Mon Sep 17 00:00:00 2001 From: "maxims@google.com" Date: Mon, 17 Apr 2017 12:00:24 -0700 Subject: aspeed: Reset Driver Add Reset Driver for ast2500 SoC. This driver uses Watchdog Timer to perform resets and thus depends on it. The actual Watchdog device used needs to be configured in Device Tree using "aspeed,wdt" property, which must be WDT phandle, for example: rst: reset-controller { compatible = "aspeed,ast2500-reset"; aspeed,wdt = <&wdt1>; } Signed-off-by: Maxim Sloyko Reviewed-by: Simon Glass --- arch/arm/include/asm/arch-aspeed/scu_ast2500.h | 28 +++++++ drivers/reset/Kconfig | 10 +++ drivers/reset/Makefile | 1 + drivers/reset/ast2500-reset.c | 106 +++++++++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 drivers/reset/ast2500-reset.c (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h index 0fa3ecb9b91..e2556f920de 100644 --- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h +++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h @@ -31,6 +31,34 @@ #define SCU_MISC_UARTCLK_DIV13 (1 << 12) +/* + * SYSRESET is actually more like a Power register, + * except that corresponding bit set to 1 means that + * the peripheral is off. + */ +#define SCU_SYSRESET_XDMA (1 << 25) +#define SCU_SYSRESET_MCTP (1 << 24) +#define SCU_SYSRESET_ADC (1 << 23) +#define SCU_SYSRESET_JTAG (1 << 22) +#define SCU_SYSRESET_MIC (1 << 18) +#define SCU_SYSRESET_SDIO (1 << 16) +#define SCU_SYSRESET_USB11HOST (1 << 15) +#define SCU_SYSRESET_USBHUB (1 << 14) +#define SCU_SYSRESET_CRT (1 << 13) +#define SCU_SYSRESET_MAC2 (1 << 12) +#define SCU_SYSRESET_MAC1 (1 << 11) +#define SCU_SYSRESET_PECI (1 << 10) +#define SCU_SYSRESET_PWM (1 << 9) +#define SCU_SYSRESET_PCI_VGA (1 << 8) +#define SCU_SYSRESET_2D (1 << 7) +#define SCU_SYSRESET_VIDEO (1 << 6) +#define SCU_SYSRESET_LPC (1 << 5) +#define SCU_SYSRESET_HAC (1 << 4) +#define SCU_SYSRESET_USBHID (1 << 3) +#define SCU_SYSRESET_I2C (1 << 2) +#define SCU_SYSRESET_AHB (1 << 1) +#define SCU_SYSRESET_SDRAM_WDT (1 << 0) + #ifndef __ASSEMBLY__ struct ast2500_clk_priv { diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index fa77ee4adae..80f4646a79c 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -51,4 +51,14 @@ config RESET_UNIPHIER Say Y if you want to control reset signals provided by System Control block, Media I/O block, Peripheral Block. +config AST2500_RESET + bool "Reset controller driver for AST2500 SoCs" + depends on DM_RESET && WDT_ASPEED + default y if ASPEED_AST2500 + help + Support for reset controller on AST2500 SoC. This controller uses + watchdog to reset different peripherals and thus only supports + resets that are supported by watchdog. The main limitation though + is that some reset signals, like I2C or MISC reset multiple devices. + endmenu diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 2b963961d6b..630b4b4e541 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_STI_RESET) += sti-reset.o obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o +obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o diff --git a/drivers/reset/ast2500-reset.c b/drivers/reset/ast2500-reset.c new file mode 100644 index 00000000000..b2c89e1f1e2 --- /dev/null +++ b/drivers/reset/ast2500-reset.c @@ -0,0 +1,106 @@ +/* + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct ast2500_reset_priv { + /* WDT used to perform resets. */ + struct udevice *wdt; + struct ast2500_scu *scu; +}; + +static int ast2500_ofdata_to_platdata(struct udevice *dev) +{ + struct ast2500_reset_priv *priv = dev_get_priv(dev); + int ret; + + ret = uclass_get_device_by_phandle(UCLASS_WDT, dev, "aspeed,wdt", + &priv->wdt); + if (ret) { + debug("%s: can't find WDT for reset controller", __func__); + return ret; + } + + return 0; +} + +static int ast2500_reset_assert(struct reset_ctl *reset_ctl) +{ + struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev); + u32 reset_mode, reset_mask; + bool reset_sdram; + int ret; + + /* + * To reset SDRAM, a specifal flag in SYSRESET register + * needs to be enabled first + */ + reset_mode = ast_reset_mode_from_flags(reset_ctl->id); + reset_mask = ast_reset_mask_from_flags(reset_ctl->id); + reset_sdram = reset_mode == WDT_CTRL_RESET_SOC && + (reset_mask & WDT_RESET_SDRAM); + + if (reset_sdram) { + ast_scu_unlock(priv->scu); + setbits_le32(&priv->scu->sysreset_ctrl1, + SCU_SYSRESET_SDRAM_WDT); + ret = wdt_expire_now(priv->wdt, reset_ctl->id); + clrbits_le32(&priv->scu->sysreset_ctrl1, + SCU_SYSRESET_SDRAM_WDT); + ast_scu_lock(priv->scu); + } else { + ret = wdt_expire_now(priv->wdt, reset_ctl->id); + } + + return ret; +} + +static int ast2500_reset_request(struct reset_ctl *reset_ctl) +{ + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, reset_ctl, + reset_ctl->dev, reset_ctl->id); + + return 0; +} + +static int ast2500_reset_probe(struct udevice *dev) +{ + struct ast2500_reset_priv *priv = dev_get_priv(dev); + + priv->scu = ast_get_scu(); + + return 0; +} + +static const struct udevice_id ast2500_reset_ids[] = { + { .compatible = "aspeed,ast2500-reset" }, + { } +}; + +struct reset_ops ast2500_reset_ops = { + .rst_assert = ast2500_reset_assert, + .request = ast2500_reset_request, +}; + +U_BOOT_DRIVER(ast2500_reset) = { + .name = "ast2500_reset", + .id = UCLASS_RESET, + .of_match = ast2500_reset_ids, + .probe = ast2500_reset_probe, + .ops = &ast2500_reset_ops, + .ofdata_to_platdata = ast2500_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct ast2500_reset_priv), +}; -- cgit v1.3.1 From 99f8ad7321fb9bbfbaff870a53b005d36a723b1f Mon Sep 17 00:00:00 2001 From: "maxims@google.com" Date: Mon, 17 Apr 2017 12:00:26 -0700 Subject: aspeed: Refactor AST2500 RAM Driver and Sysreset Driver This change switches all existing users of ast2500 Watchdog to Driver Model based Watchdog driver. To perform system reset Sysreset Driver uses first Watchdog device found via uclass_first_device call. Since the system is going to be reset anyway it does not make much difference which watchdog is used. Instead of using Watchdog to reset itself, SDRAM driver now uses Reset driver to do that. These were the only users of the old Watchdog API, so that API is removed. This all is done in one change to avoid having to maintain dual API for watchdog in between. Signed-off-by: Maxim Sloyko Reviewed-by: Simon Glass --- arch/arm/include/asm/arch-aspeed/wdt.h | 39 --------------------- arch/arm/mach-aspeed/Kconfig | 8 +---- arch/arm/mach-aspeed/ast2500/sdram_ast2500.c | 12 +++++-- arch/arm/mach-aspeed/ast_wdt.c | 51 ---------------------------- configs/evb-ast2500_defconfig | 2 ++ drivers/sysreset/sysreset_ast.c | 24 ++++++------- 6 files changed, 24 insertions(+), 112 deletions(-) (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-aspeed/wdt.h b/arch/arm/include/asm/arch-aspeed/wdt.h index 981fa05a567..db8ecbcbe4a 100644 --- a/arch/arm/include/asm/arch-aspeed/wdt.h +++ b/arch/arm/include/asm/arch-aspeed/wdt.h @@ -100,45 +100,6 @@ u32 ast_reset_mask_from_flags(ulong flags); * @reset_mask: Reset Mask */ ulong ast_flags_from_reset_mode_mask(u32 reset_mode, u32 reset_mask); - -#ifndef CONFIG_WDT -/** - * Stop WDT - * - * @wdt: watchdog to stop - * - * When using driver model this function has different signature - */ -void wdt_stop(struct ast_wdt *wdt); - -/** - * Stop WDT - * - * @wdt: watchdog to start - * @timeout watchdog timeout in number of clock ticks - * - * When using driver model this function has different signature - */ -void wdt_start(struct ast_wdt *wdt, u32 timeout); -#endif /* CONFIG_WDT */ - -/** - * Reset peripherals specified by mask - * - * Note, that this is only supported by ast2500 SoC - * - * @wdt: watchdog to use for this reset - * @mask: reset mask. - */ -int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask); - -/** - * ast_get_wdt() - get a pointer to watchdog registers - * - * @wdt_number: 0-based WDT peripheral number - * @return pointer to registers or -ve error on error - */ -struct ast_wdt *ast_get_wdt(u8 wdt_number); #endif /* __ASSEMBLY__ */ #endif /* _ASM_ARCH_WDT_H */ diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig index c5b90bd96a4..4f021baa062 100644 --- a/arch/arm/mach-aspeed/Kconfig +++ b/arch/arm/mach-aspeed/Kconfig @@ -11,19 +11,13 @@ config SYS_TEXT_BASE config ASPEED_AST2500 bool "Support Aspeed AST2500 SoC" + depends on DM_RESET select CPU_ARM1176 help The Aspeed AST2500 is a ARM-based SoC with arm1176 CPU. It is used as Board Management Controller on many server boards, which is enabled by support of LPC and eSPI peripherals. -config WDT_NUM - int "Number of Watchdog Timers" - default 3 if ASPEED_AST2500 - help - The number of Watchdot Timers on a SoC. - AST2500 has three WDTsk earlier versions have two or fewer. - source "arch/arm/mach-aspeed/ast2500/Kconfig" endif diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c index cb6e03fa342..efcf452b178 100644 --- a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c +++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -328,6 +329,7 @@ static void ast2500_sdrammc_lock(struct dram_info *info) static int ast2500_sdrammc_probe(struct udevice *dev) { + struct reset_ctl reset_ctl; struct dram_info *priv = (struct dram_info *)dev_get_priv(dev); struct ast2500_sdrammc_regs *regs = priv->regs; int i; @@ -345,9 +347,15 @@ static int ast2500_sdrammc_probe(struct udevice *dev) } clk_set_rate(&priv->ddr_clk, priv->clock_rate); - ret = ast_wdt_reset_masked(ast_get_wdt(0), WDT_RESET_SDRAM); + ret = reset_get_by_index(dev, 0, &reset_ctl); if (ret) { - debug("%s(): SDRAM reset failed\n", __func__); + debug("%s(): Failed to get reset signal\n", __func__); + return ret; + } + + ret = reset_assert(&reset_ctl); + if (ret) { + debug("%s(): SDRAM reset failed: %u\n", __func__, ret); return ret; } diff --git a/arch/arm/mach-aspeed/ast_wdt.c b/arch/arm/mach-aspeed/ast_wdt.c index 895fba3366c..1a858b1020f 100644 --- a/arch/arm/mach-aspeed/ast_wdt.c +++ b/arch/arm/mach-aspeed/ast_wdt.c @@ -28,54 +28,3 @@ ulong ast_flags_from_reset_mode_mask(u32 reset_mode, u32 reset_mask) return ret; } - -#ifndef CONFIG_WDT -void wdt_stop(struct ast_wdt *wdt) -{ - clrbits_le32(&wdt->ctrl, WDT_CTRL_EN); -} - -void wdt_start(struct ast_wdt *wdt, u32 timeout) -{ - writel(timeout, &wdt->counter_reload_val); - writel(WDT_COUNTER_RESTART_VAL, &wdt->counter_restart); - /* - * Setting CLK1MHZ bit is just for compatibility with ast2400 part. - * On ast2500 watchdog timer clock is fixed at 1MHz and the bit is - * read-only - */ - setbits_le32(&wdt->ctrl, - WDT_CTRL_EN | WDT_CTRL_RESET | WDT_CTRL_CLK1MHZ); -} -#endif /* CONFIG_WDT */ - -int ast_wdt_reset_masked(struct ast_wdt *wdt, u32 mask) -{ -#ifdef CONFIG_ASPEED_AST2500 - if (!mask) - return -EINVAL; - - writel(mask, &wdt->reset_mask); - clrbits_le32(&wdt->ctrl, - WDT_CTRL_RESET_MASK << WDT_CTRL_RESET_MODE_SHIFT); - wdt_start(wdt, 1); - - /* Wait for WDT to reset */ - while (readl(&wdt->ctrl) & WDT_CTRL_EN) - ; - wdt_stop(wdt); - - return 0; -#else - return -EINVAL; -#endif -} - -struct ast_wdt *ast_get_wdt(u8 wdt_number) -{ - if (wdt_number > CONFIG_WDT_NUM - 1) - return ERR_PTR(-EINVAL); - - return (struct ast_wdt *)(WDT_BASE + - sizeof(struct ast_wdt) * wdt_number); -} diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig index cc5fea9a814..74808a71ee6 100644 --- a/configs/evb-ast2500_defconfig +++ b/configs/evb-ast2500_defconfig @@ -15,3 +15,5 @@ CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SYSRESET=y CONFIG_TIMER=y +CONFIG_WDT=y +CONFIG_DM_RESET=y diff --git a/drivers/sysreset/sysreset_ast.c b/drivers/sysreset/sysreset_ast.c index a0ab12851d4..3c3f552df83 100644 --- a/drivers/sysreset/sysreset_ast.c +++ b/drivers/sysreset/sysreset_ast.c @@ -8,21 +8,19 @@ #include #include #include +#include #include #include #include -/* Number of Watchdog Timer ticks before reset */ -#define AST_WDT_RESET_TIMEOUT 10 -#define AST_WDT_FOR_RESET 0 - static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type) { - struct ast_wdt *wdt = ast_get_wdt(AST_WDT_FOR_RESET); - u32 reset_mode = 0; + struct udevice *wdt; + u32 reset_mode; + int ret = uclass_first_device(UCLASS_WDT, &wdt); - if (IS_ERR(wdt)) - return PTR_ERR(wdt); + if (ret) + return ret; switch (type) { case SYSRESET_WARM: @@ -35,11 +33,11 @@ static int ast_sysreset_request(struct udevice *dev, enum sysreset_t type) return -EPROTONOSUPPORT; } - /* Clear reset mode bits */ - clrsetbits_le32(&wdt->ctrl, - (WDT_CTRL_RESET_MODE_MASK << WDT_CTRL_RESET_MODE_SHIFT), - (reset_mode << WDT_CTRL_RESET_MODE_SHIFT)); - wdt_start(wdt, AST_WDT_RESET_TIMEOUT); + ret = wdt_expire_now(wdt, reset_mode); + if (ret) { + debug("Sysreset failed: %d", ret); + return ret; + } return -EINPROGRESS; } -- cgit v1.3.1 From 4f0e44e46615e3c827dcd1ec59677be1058d394c Mon Sep 17 00:00:00 2001 From: "maxims@google.com" Date: Mon, 17 Apr 2017 12:00:27 -0700 Subject: aspeed: AST2500 Pinctrl Driver This driver uses Generic Pinctrl framework and is compatible with the Linux driver for ast2500: it uses the same device tree configuration. Not all pins are supported by the driver at the moment, so it actually compatible with ast2400. In general, however, there are differences that in the future would be easier to maintain separately. Signed-off-by: Maxim Sloyko Reviewed-by: Simon Glass --- arch/arm/include/asm/arch-aspeed/pinctrl.h | 52 ++++++++++ arch/arm/include/asm/arch-aspeed/scu_ast2500.h | 19 ++++ drivers/pinctrl/Kconfig | 9 ++ drivers/pinctrl/Makefile | 1 + drivers/pinctrl/aspeed/Makefile | 1 + drivers/pinctrl/aspeed/pinctrl_ast2500.c | 127 +++++++++++++++++++++++++ 6 files changed, 209 insertions(+) create mode 100644 arch/arm/include/asm/arch-aspeed/pinctrl.h create mode 100644 drivers/pinctrl/aspeed/Makefile create mode 100644 drivers/pinctrl/aspeed/pinctrl_ast2500.c (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-aspeed/pinctrl.h b/arch/arm/include/asm/arch-aspeed/pinctrl.h new file mode 100644 index 00000000000..365dc21dbc4 --- /dev/null +++ b/arch/arm/include/asm/arch-aspeed/pinctrl.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _ASM_ARCH_PERIPH_H +#define _ASM_ARCH_PERIPH_H + +/* + * Peripherals supported by the hardware. + * These are used to specify pinctrl settings. + */ + +enum periph_id { + PERIPH_ID_UART1, + PERIPH_ID_UART2, + PERIPH_ID_UART3, + PERIPH_ID_UART4, + PERIPH_ID_LPC, + PERIPH_ID_PWM0, + PERIPH_ID_PWM1, + PERIPH_ID_PWM2, + PERIPH_ID_PWM3, + PERIPH_ID_PWM4, + PERIPH_ID_PWM5, + PERIPH_ID_PWM6, + PERIPH_ID_PWM7, + PERIPH_ID_PWM8, + PERIPH_ID_MAC1, + PERIPH_ID_MAC2, + PERIPH_ID_VIDEO, + PERIPH_ID_SPI1, + PERIPH_ID_SPI2, + PERIPH_ID_I2C1, + PERIPH_ID_I2C2, + PERIPH_ID_I2C3, + PERIPH_ID_I2C4, + PERIPH_ID_I2C5, + PERIPH_ID_I2C6, + PERIPH_ID_I2C7, + PERIPH_ID_I2C8, + PERIPH_ID_I2C9, + PERIPH_ID_I2C10, + PERIPH_ID_I2C11, + PERIPH_ID_I2C12, + PERIPH_ID_I2C13, + PERIPH_ID_I2C14, + PERIPH_ID_SD1, + PERIPH_ID_SD2, +}; + +#endif /* _ASM_ARCH_SCU_AST2500_H */ diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h index e2556f920de..1cdd3b91982 100644 --- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h +++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h @@ -10,6 +10,8 @@ #define SCU_HWSTRAP_VGAMEM_MASK 3 #define SCU_HWSTRAP_VGAMEM_SHIFT 2 +#define SCU_HWSTRAP_MAC1_RGMII (1 << 6) +#define SCU_HWSTRAP_MAC2_RGMII (1 << 7) #define SCU_HWSTRAP_DDR4 (1 << 24) #define SCU_HWSTRAP_CLKIN_25MHZ (1 << 23) @@ -59,6 +61,23 @@ #define SCU_SYSRESET_AHB (1 << 1) #define SCU_SYSRESET_SDRAM_WDT (1 << 0) +/* Bits 16-27 in the register control pin functions for I2C devices 3-14 */ +#define SCU_PINMUX_CTRL5_I2C (1 << 16) + +/* + * The values are grouped by function, not by register. + * They are actually scattered across multiple loosely related registers. + */ +#define SCU_PIN_FUN_MAC1_MDC (1 << 30) +#define SCU_PIN_FUN_MAC1_MDIO (1 << 31) +#define SCU_PIN_FUN_MAC1_PHY_LINK (1 << 0) +#define SCU_PIN_FUN_MAC2_MDIO (1 << 2) +#define SCU_PIN_FUN_MAC2_PHY_LINK (1 << 1) +#define SCU_PIN_FUN_SCL1 (1 << 12) +#define SCU_PIN_FUN_SCL2 (1 << 14) +#define SCU_PIN_FUN_SDA1 (1 << 13) +#define SCU_PIN_FUN_SDA2 (1 << 15) + #ifndef __ASSEMBLY__ struct ast2500_clk_priv { diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 9cea6f202cf..f6616c5329b 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -248,6 +248,15 @@ config PINCTRL_STM32 the GPIO definitions and pin control functions for each available multiplex function. +config ASPEED_AST2500_PINCTRL + bool "Aspeed AST2500 pin control driver" + depends on DM && PINCTRL_GENERIC && ASPEED_AST2500 + default y + help + Support pin multiplexing control on Aspeed ast2500 SoC. The driver uses + Generic Pinctrl framework and is compatible with the Linux driver, + i.e. it uses the same device tree configuration. + endif source "drivers/pinctrl/meson/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 17a7173d355..1e5c4257c4d 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC) += pinctrl-generic.o obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o obj-y += nxp/ +obj-$(CONFIG_ARCH_ASPEED) += aspeed/ obj-$(CONFIG_ARCH_ATH79) += ath79/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o diff --git a/drivers/pinctrl/aspeed/Makefile b/drivers/pinctrl/aspeed/Makefile new file mode 100644 index 00000000000..2e6ed604c8f --- /dev/null +++ b/drivers/pinctrl/aspeed/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ASPEED_AST2500_PINCTRL) += pinctrl_ast2500.o diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c b/drivers/pinctrl/aspeed/pinctrl_ast2500.c new file mode 100644 index 00000000000..01f97c1b48d --- /dev/null +++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c @@ -0,0 +1,127 @@ +/* + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* + * This driver works with very simple configuration that has the same name + * for group and function. This way it is compatible with the Linux Kernel + * driver. + */ + +struct ast2500_pinctrl_priv { + struct ast2500_scu *scu; +}; + +static int ast2500_pinctrl_probe(struct udevice *dev) +{ + struct ast2500_pinctrl_priv *priv = dev_get_priv(dev); + + priv->scu = ast_get_scu(); + + return 0; +} + +struct ast2500_group_config { + char *group_name; + /* Control register number (1-10) */ + unsigned reg_num; + /* The mask of control bits in the register */ + u32 ctrl_bit_mask; +}; + +static const struct ast2500_group_config ast2500_groups[] = { + { "I2C1", 8, (1 << 13) | (1 << 12) }, + { "I2C2", 8, (1 << 15) | (1 << 14) }, + { "I2C3", 8, (1 << 16) }, + { "I2C4", 5, (1 << 17) }, + { "I2C4", 5, (1 << 17) }, + { "I2C5", 5, (1 << 18) }, + { "I2C6", 5, (1 << 19) }, + { "I2C7", 5, (1 << 20) }, + { "I2C8", 5, (1 << 21) }, + { "I2C9", 5, (1 << 22) }, + { "I2C10", 5, (1 << 23) }, + { "I2C11", 5, (1 << 24) }, + { "I2C12", 5, (1 << 25) }, + { "I2C13", 5, (1 << 26) }, + { "I2C14", 5, (1 << 27) }, + { "MAC1LINK", 1, (1 << 0) }, + { "MDIO1", 3, (1 << 31) | (1 << 30) }, + { "MAC2LINK", 1, (1 << 1) }, + { "MDIO2", 5, (1 << 2) }, +}; + +static int ast2500_pinctrl_get_groups_count(struct udevice *dev) +{ + debug("PINCTRL: get_(functions/groups)_count\n"); + + return ARRAY_SIZE(ast2500_groups); +} + +static const char *ast2500_pinctrl_get_group_name(struct udevice *dev, + unsigned selector) +{ + debug("PINCTRL: get_(function/group)_name %u\n", selector); + + return ast2500_groups[selector].group_name; +} + +static int ast2500_pinctrl_group_set(struct udevice *dev, unsigned selector, + unsigned func_selector) +{ + struct ast2500_pinctrl_priv *priv = dev_get_priv(dev); + const struct ast2500_group_config *config; + u32 *ctrl_reg; + + debug("PINCTRL: group_set <%u, %u>\n", selector, func_selector); + if (selector >= ARRAY_SIZE(ast2500_groups)) + return -EINVAL; + + config = &ast2500_groups[selector]; + if (config->reg_num > 6) + ctrl_reg = &priv->scu->pinmux_ctrl1[config->reg_num - 7]; + else + ctrl_reg = &priv->scu->pinmux_ctrl[config->reg_num - 1]; + + ast_scu_unlock(priv->scu); + setbits_le32(ctrl_reg, config->ctrl_bit_mask); + ast_scu_lock(priv->scu); + + return 0; +} + +static struct pinctrl_ops ast2500_pinctrl_ops = { + .set_state = pinctrl_generic_set_state, + .get_groups_count = ast2500_pinctrl_get_groups_count, + .get_group_name = ast2500_pinctrl_get_group_name, + .get_functions_count = ast2500_pinctrl_get_groups_count, + .get_function_name = ast2500_pinctrl_get_group_name, + .pinmux_group_set = ast2500_pinctrl_group_set, +}; + +static const struct udevice_id ast2500_pinctrl_ids[] = { + { .compatible = "aspeed,ast2500-pinctrl" }, + { .compatible = "aspeed,g5-pinctrl" }, + { } +}; + +U_BOOT_DRIVER(pinctrl_ast2500) = { + .name = "aspeed_ast2500_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = ast2500_pinctrl_ids, + .priv_auto_alloc_size = sizeof(struct ast2500_pinctrl_priv), + .ops = &ast2500_pinctrl_ops, + .probe = ast2500_pinctrl_probe, +}; -- cgit v1.3.1 From 4999bb06cc2f21d3a517a068b183fb11827f49a7 Mon Sep 17 00:00:00 2001 From: "maxims@google.com" Date: Mon, 17 Apr 2017 12:00:29 -0700 Subject: aspeed: Add P-Bus clock in ast2500 clock driver Add P-Bus Clock support to ast2500 clock driver. This is the clock used by I2C devices. Signed-off-by: Maxim Sloyko Reviewed-by: Simon Glass --- arch/arm/include/asm/arch-aspeed/scu_ast2500.h | 3 ++- drivers/clk/aspeed/clk_ast2500.c | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h index 1cdd3b91982..319d75e05ce 100644 --- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h +++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h @@ -21,7 +21,8 @@ #define SCU_MPLL_NUM_MASK 0xff #define SCU_MPLL_POST_SHIFT 13 #define SCU_MPLL_POST_MASK 0x3f - +#define SCU_PCLK_DIV_SHIFT 23 +#define SCU_PCLK_DIV_MASK 7 #define SCU_HPLL_DENUM_SHIFT 0 #define SCU_HPLL_DENUM_MASK 0x1f #define SCU_HPLL_NUM_SHIFT 5 diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c index 504731271c3..9e4c66ea85f 100644 --- a/drivers/clk/aspeed/clk_ast2500.c +++ b/drivers/clk/aspeed/clk_ast2500.c @@ -110,6 +110,17 @@ static ulong ast2500_clk_get_rate(struct clk *clk) rate = ast2500_get_mpll_rate(clkin, readl(&priv->scu->m_pll_param)); break; + case BCLK_PCLK: + { + ulong apb_div = 4 + 4 * ((readl(&priv->scu->clk_sel1) + >> SCU_PCLK_DIV_SHIFT) & + SCU_PCLK_DIV_MASK); + rate = ast2500_get_hpll_rate(clkin, + readl(&priv->scu-> + h_pll_param)); + rate = rate / apb_div; + } + break; case PCLK_UART1: rate = ast2500_get_uart_clk_rate(priv->scu, 1); break; -- cgit v1.3.1 From 4dc038f3a1c1b88b9b77afdcb1081fc399e5085a Mon Sep 17 00:00:00 2001 From: "maxims@google.com" Date: Mon, 17 Apr 2017 12:00:30 -0700 Subject: aspeed: Add I2C Driver Add Device Model based I2C driver for ast2500/ast2400 SoCs. The driver is very limited, it only supports master mode and synchronous byte-by-byte reads/writes, no DMA or Pool Buffers. Signed-off-by: Maxim Sloyko Reviewed-by: Simon Glass Acked-by: Heiko Schocher --- drivers/i2c/Kconfig | 9 ++ drivers/i2c/Makefile | 1 + drivers/i2c/ast_i2c.c | 357 ++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/ast_i2c.h | 132 +++++++++++++++++++ 4 files changed, 499 insertions(+) create mode 100644 drivers/i2c/ast_i2c.c create mode 100644 drivers/i2c/ast_i2c.h (limited to 'drivers') diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 4e9afc120a3..c58bc1e1cf5 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -114,6 +114,15 @@ config SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED enable status register. This config option can be enabled in such cases. +config SYS_I2C_ASPEED + bool "Aspeed I2C Controller" + depends on DM_I2C && ARCH_ASPEED + help + Say yes here to select Aspeed I2C Host Controller. The driver + supports AST2500 and AST2400 controllers, but is very limited. + Only single master mode is supported and only byte-by-byte + synchronous reads and writes are supported, no Pool Buffers or DMA. + config SYS_I2C_INTEL bool "Intel I2C/SMBUS driver" depends on DM_I2C diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 4872c1d7022..d20fe7bb4ae 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_I2C_MV) += mv_i2c.o obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o obj-$(CONFIG_SYS_I2C) += i2c_core.o +obj-$(CONFIG_SYS_I2C_ASPEED) += ast_i2c.o obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o diff --git a/drivers/i2c/ast_i2c.c b/drivers/i2c/ast_i2c.c new file mode 100644 index 00000000000..16dfb570669 --- /dev/null +++ b/drivers/i2c/ast_i2c.c @@ -0,0 +1,357 @@ +/* + * Copyright (C) 2012-2020 ASPEED Technology Inc. + * Copyright 2016 IBM Corporation + * Copyright 2017 Google, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ast_i2c.h" + +#define I2C_TIMEOUT_US 100000 +#define I2C_SLEEP_STEP_US 20 + +#define HIGHSPEED_TTIMEOUT 3 + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Device private data + */ +struct ast_i2c_priv { + /* This device's clock */ + struct clk clk; + /* Device registers */ + struct ast_i2c_regs *regs; + /* I2C speed in Hz */ + int speed; +}; + +/* + * Given desired divider ratio, return the value that needs to be set + * in Clock and AC Timing Control register + */ +static u32 get_clk_reg_val(ulong divider_ratio) +{ + ulong inc = 0, div; + ulong scl_low, scl_high, data; + + for (div = 0; divider_ratio >= 16; div++) { + inc |= (divider_ratio & 1); + divider_ratio >>= 1; + } + divider_ratio += inc; + scl_low = (divider_ratio >> 1) - 1; + scl_high = divider_ratio - scl_low - 2; + data = I2CD_CACTC_BASE + | (scl_high << I2CD_TCKHIGH_SHIFT) + | (scl_low << I2CD_TCKLOW_SHIFT) + | (div << I2CD_BASE_DIV_SHIFT); + + return data; +} + +static void ast_i2c_clear_interrupts(struct udevice *dev) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + + writel(~0, &priv->regs->isr); +} + +static void ast_i2c_init_bus(struct udevice *dev) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + + /* Reset device */ + writel(0, &priv->regs->fcr); + /* Enable Master Mode. Assuming single-master */ + writel(I2CD_MASTER_EN + | I2CD_M_SDA_LOCK_EN + | I2CD_MULTI_MASTER_DIS | I2CD_M_SCL_DRIVE_EN, + &priv->regs->fcr); + /* Enable Interrupts */ + writel(I2CD_INTR_TX_ACK + | I2CD_INTR_TX_NAK + | I2CD_INTR_RX_DONE + | I2CD_INTR_BUS_RECOVER_DONE + | I2CD_INTR_NORMAL_STOP + | I2CD_INTR_ABNORMAL, &priv->regs->icr); +} + +static int ast_i2c_ofdata_to_platdata(struct udevice *dev) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + int ret; + + priv->regs = dev_get_addr_ptr(dev); + if (IS_ERR(priv->regs)) + return PTR_ERR(priv->regs); + + ret = clk_get_by_index(dev, 0, &priv->clk); + if (ret < 0) { + debug("%s: Can't get clock for %s: %d\n", __func__, dev->name, + ret); + return ret; + } + + return 0; +} + +static int ast_i2c_probe(struct udevice *dev) +{ + struct ast2500_scu *scu; + + debug("Enabling I2C%u\n", dev->seq); + + /* + * Get all I2C devices out of Reset. + * Only needs to be done once, but doing it for every + * device does not hurt. + */ + scu = ast_get_scu(); + ast_scu_unlock(scu); + clrbits_le32(&scu->sysreset_ctrl1, SCU_SYSRESET_I2C); + ast_scu_lock(scu); + + ast_i2c_init_bus(dev); + + return 0; +} + +static int ast_i2c_wait_isr(struct udevice *dev, u32 flag) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + int timeout = I2C_TIMEOUT_US; + + while (!(readl(&priv->regs->isr) & flag) && timeout > 0) { + udelay(I2C_SLEEP_STEP_US); + timeout -= I2C_SLEEP_STEP_US; + } + + ast_i2c_clear_interrupts(dev); + if (timeout <= 0) + return -ETIMEDOUT; + + return 0; +} + +static int ast_i2c_send_stop(struct udevice *dev) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + + writel(I2CD_M_STOP_CMD, &priv->regs->csr); + + return ast_i2c_wait_isr(dev, I2CD_INTR_NORMAL_STOP); +} + +static int ast_i2c_wait_tx(struct udevice *dev) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + int timeout = I2C_TIMEOUT_US; + u32 flag = I2CD_INTR_TX_ACK | I2CD_INTR_TX_NAK; + u32 status = readl(&priv->regs->isr) & flag; + int ret = 0; + + while (!status && timeout > 0) { + status = readl(&priv->regs->isr) & flag; + udelay(I2C_SLEEP_STEP_US); + timeout -= I2C_SLEEP_STEP_US; + } + + if (status == I2CD_INTR_TX_NAK) + ret = -EREMOTEIO; + + if (timeout <= 0) + ret = -ETIMEDOUT; + + ast_i2c_clear_interrupts(dev); + + return ret; +} + +static int ast_i2c_start_txn(struct udevice *dev, uint devaddr) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + + /* Start and Send Device Address */ + writel(devaddr, &priv->regs->trbbr); + writel(I2CD_M_START_CMD | I2CD_M_TX_CMD, &priv->regs->csr); + + return ast_i2c_wait_tx(dev); +} + +static int ast_i2c_read_data(struct udevice *dev, u8 chip_addr, u8 *buffer, + size_t len, bool send_stop) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + u32 i2c_cmd = I2CD_M_RX_CMD; + int ret; + + ret = ast_i2c_start_txn(dev, (chip_addr << 1) | I2C_M_RD); + if (ret < 0) + return ret; + + for (; len > 0; len--, buffer++) { + if (len == 1) + i2c_cmd |= I2CD_M_S_RX_CMD_LAST; + writel(i2c_cmd, &priv->regs->csr); + ret = ast_i2c_wait_isr(dev, I2CD_INTR_RX_DONE); + if (ret < 0) + return ret; + *buffer = (readl(&priv->regs->trbbr) & I2CD_RX_DATA_MASK) + >> I2CD_RX_DATA_SHIFT; + } + ast_i2c_clear_interrupts(dev); + + if (send_stop) + return ast_i2c_send_stop(dev); + + return 0; +} + +static int ast_i2c_write_data(struct udevice *dev, u8 chip_addr, u8 + *buffer, size_t len, bool send_stop) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + int ret; + + ret = ast_i2c_start_txn(dev, (chip_addr << 1)); + if (ret < 0) + return ret; + + for (; len > 0; len--, buffer++) { + writel(*buffer, &priv->regs->trbbr); + writel(I2CD_M_TX_CMD, &priv->regs->csr); + ret = ast_i2c_wait_tx(dev); + if (ret < 0) + return ret; + } + + if (send_stop) + return ast_i2c_send_stop(dev); + + return 0; +} + +static int ast_i2c_deblock(struct udevice *dev) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + struct ast_i2c_regs *regs = priv->regs; + u32 csr = readl(®s->csr); + bool sda_high = csr & I2CD_SDA_LINE_STS; + bool scl_high = csr & I2CD_SCL_LINE_STS; + int ret = 0; + + if (sda_high && scl_high) { + /* Bus is idle, no deblocking needed. */ + return 0; + } else if (sda_high) { + /* Send stop command */ + debug("Unterminated TXN in (%x), sending stop\n", csr); + ret = ast_i2c_send_stop(dev); + } else if (scl_high) { + /* Possibly stuck slave */ + debug("Bus stuck (%x), attempting recovery\n", csr); + writel(I2CD_BUS_RECOVER_CMD, ®s->csr); + ret = ast_i2c_wait_isr(dev, I2CD_INTR_BUS_RECOVER_DONE); + } else { + /* Just try to reinit the device. */ + ast_i2c_init_bus(dev); + } + + return ret; +} + +static int ast_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) +{ + int ret; + + ret = ast_i2c_deblock(dev); + if (ret < 0) + return ret; + + debug("i2c_xfer: %d messages\n", nmsgs); + for (; nmsgs > 0; nmsgs--, msg++) { + if (msg->flags & I2C_M_RD) { + debug("i2c_read: chip=0x%x, len=0x%x, flags=0x%x\n", + msg->addr, msg->len, msg->flags); + ret = ast_i2c_read_data(dev, msg->addr, msg->buf, + msg->len, (nmsgs == 1)); + } else { + debug("i2c_write: chip=0x%x, len=0x%x, flags=0x%x\n", + msg->addr, msg->len, msg->flags); + ret = ast_i2c_write_data(dev, msg->addr, msg->buf, + msg->len, (nmsgs == 1)); + } + if (ret) { + debug("%s: error (%d)\n", __func__, ret); + return -EREMOTEIO; + } + } + + return 0; +} + +static int ast_i2c_set_speed(struct udevice *dev, unsigned int speed) +{ + struct ast_i2c_priv *priv = dev_get_priv(dev); + struct ast_i2c_regs *regs = priv->regs; + ulong i2c_rate, divider; + + debug("Setting speed for I2C%d to <%u>\n", dev->seq, speed); + if (!speed) { + debug("No valid speed specified\n"); + return -EINVAL; + } + + i2c_rate = clk_get_rate(&priv->clk); + divider = i2c_rate / speed; + + priv->speed = speed; + if (speed > I2C_HIGHSPEED_RATE) { + debug("Enable High Speed\n"); + setbits_le32(®s->fcr, I2CD_M_HIGH_SPEED_EN + | I2CD_M_SDA_DRIVE_1T_EN + | I2CD_SDA_DRIVE_1T_EN); + writel(HIGHSPEED_TTIMEOUT, ®s->cactcr2); + } else { + debug("Enabling Normal Speed\n"); + writel(I2CD_NO_TIMEOUT_CTRL, ®s->cactcr2); + } + + writel(get_clk_reg_val(divider), ®s->cactcr1); + ast_i2c_clear_interrupts(dev); + + return 0; +} + +static const struct dm_i2c_ops ast_i2c_ops = { + .xfer = ast_i2c_xfer, + .set_bus_speed = ast_i2c_set_speed, + .deblock = ast_i2c_deblock, +}; + +static const struct udevice_id ast_i2c_ids[] = { + { .compatible = "aspeed,ast2400-i2c-bus" }, + { .compatible = "aspeed,ast2500-i2c-bus" }, + { }, +}; + +U_BOOT_DRIVER(ast_i2c) = { + .name = "ast_i2c", + .id = UCLASS_I2C, + .of_match = ast_i2c_ids, + .probe = ast_i2c_probe, + .ofdata_to_platdata = ast_i2c_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct ast_i2c_priv), + .ops = &ast_i2c_ops, +}; diff --git a/drivers/i2c/ast_i2c.h b/drivers/i2c/ast_i2c.h new file mode 100644 index 00000000000..e5dec7a480c --- /dev/null +++ b/drivers/i2c/ast_i2c.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2012-2020 ASPEED Technology Inc. + * Copyright 2016 IBM Corporation + * Copyright 2017 Google, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __AST_I2C_H_ +#define __AST_I2C_H_ + +struct ast_i2c_regs { + u32 fcr; + u32 cactcr1; + u32 cactcr2; + u32 icr; + u32 isr; + u32 csr; + u32 sdar; + u32 pbcr; + u32 trbbr; +#ifdef CONFIG_ASPEED_AST2500 + u32 dma_mbar; + u32 dma_tlr; +#endif +}; + +/* Device Register Definition */ +/* 0x00 : I2CD Function Control Register */ +#define I2CD_BUFF_SEL_MASK (0x7 << 20) +#define I2CD_BUFF_SEL(x) (x << 20) +#define I2CD_M_SDA_LOCK_EN (0x1 << 16) +#define I2CD_MULTI_MASTER_DIS (0x1 << 15) +#define I2CD_M_SCL_DRIVE_EN (0x1 << 14) +#define I2CD_MSB_STS (0x1 << 9) +#define I2CD_SDA_DRIVE_1T_EN (0x1 << 8) +#define I2CD_M_SDA_DRIVE_1T_EN (0x1 << 7) +#define I2CD_M_HIGH_SPEED_EN (0x1 << 6) +#define I2CD_DEF_ADDR_EN (0x1 << 5) +#define I2CD_DEF_ALERT_EN (0x1 << 4) +#define I2CD_DEF_ARP_EN (0x1 << 3) +#define I2CD_DEF_GCALL_EN (0x1 << 2) +#define I2CD_SLAVE_EN (0x1 << 1) +#define I2CD_MASTER_EN (0x1) + +/* 0x04 : I2CD Clock and AC Timing Control Register #1 */ +/* Base register value. These bits are always set by the driver. */ +#define I2CD_CACTC_BASE 0xfff00300 +#define I2CD_TCKHIGH_SHIFT 16 +#define I2CD_TCKLOW_SHIFT 12 +#define I2CD_THDDAT_SHIFT 10 +#define I2CD_TO_DIV_SHIFT 8 +#define I2CD_BASE_DIV_SHIFT 0 + +/* 0x08 : I2CD Clock and AC Timing Control Register #2 */ +#define I2CD_tTIMEOUT 1 +#define I2CD_NO_TIMEOUT_CTRL 0 + +/* 0x0c : I2CD Interrupt Control Register & + * 0x10 : I2CD Interrupt Status Register + * + * These share bit definitions, so use the same values for the enable & + * status bits. + */ +#define I2CD_INTR_SDA_DL_TIMEOUT (0x1 << 14) +#define I2CD_INTR_BUS_RECOVER_DONE (0x1 << 13) +#define I2CD_INTR_SMBUS_ALERT (0x1 << 12) +#define I2CD_INTR_SMBUS_ARP_ADDR (0x1 << 11) +#define I2CD_INTR_SMBUS_DEV_ALERT_ADDR (0x1 << 10) +#define I2CD_INTR_SMBUS_DEF_ADDR (0x1 << 9) +#define I2CD_INTR_GCALL_ADDR (0x1 << 8) +#define I2CD_INTR_SLAVE_MATCH (0x1 << 7) +#define I2CD_INTR_SCL_TIMEOUT (0x1 << 6) +#define I2CD_INTR_ABNORMAL (0x1 << 5) +#define I2CD_INTR_NORMAL_STOP (0x1 << 4) +#define I2CD_INTR_ARBIT_LOSS (0x1 << 3) +#define I2CD_INTR_RX_DONE (0x1 << 2) +#define I2CD_INTR_TX_NAK (0x1 << 1) +#define I2CD_INTR_TX_ACK (0x1 << 0) + +/* 0x14 : I2CD Command/Status Register */ +#define I2CD_SDA_OE (0x1 << 28) +#define I2CD_SDA_O (0x1 << 27) +#define I2CD_SCL_OE (0x1 << 26) +#define I2CD_SCL_O (0x1 << 25) +#define I2CD_TX_TIMING (0x1 << 24) +#define I2CD_TX_STATUS (0x1 << 23) + +/* Tx State Machine */ +#define I2CD_IDLE 0x0 +#define I2CD_MACTIVE 0x8 +#define I2CD_MSTART 0x9 +#define I2CD_MSTARTR 0xa +#define I2CD_MSTOP 0xb +#define I2CD_MTXD 0xc +#define I2CD_MRXACK 0xd +#define I2CD_MRXD 0xe +#define I2CD_MTXACK 0xf +#define I2CD_SWAIT 0x1 +#define I2CD_SRXD 0x4 +#define I2CD_STXACK 0x5 +#define I2CD_STXD 0x6 +#define I2CD_SRXACK 0x7 +#define I2CD_RECOVER 0x3 + +#define I2CD_SCL_LINE_STS (0x1 << 18) +#define I2CD_SDA_LINE_STS (0x1 << 17) +#define I2CD_BUS_BUSY_STS (0x1 << 16) +#define I2CD_SDA_OE_OUT_DIR (0x1 << 15) +#define I2CD_SDA_O_OUT_DIR (0x1 << 14) +#define I2CD_SCL_OE_OUT_DIR (0x1 << 13) +#define I2CD_SCL_O_OUT_DIR (0x1 << 12) +#define I2CD_BUS_RECOVER_CMD (0x1 << 11) +#define I2CD_S_ALT_EN (0x1 << 10) +#define I2CD_RX_DMA_ENABLE (0x1 << 9) +#define I2CD_TX_DMA_ENABLE (0x1 << 8) + +/* Command Bit */ +#define I2CD_RX_BUFF_ENABLE (0x1 << 7) +#define I2CD_TX_BUFF_ENABLE (0x1 << 6) +#define I2CD_M_STOP_CMD (0x1 << 5) +#define I2CD_M_S_RX_CMD_LAST (0x1 << 4) +#define I2CD_M_RX_CMD (0x1 << 3) +#define I2CD_S_TX_CMD (0x1 << 2) +#define I2CD_M_TX_CMD (0x1 << 1) +#define I2CD_M_START_CMD 0x1 + +#define I2CD_RX_DATA_SHIFT 8 +#define I2CD_RX_DATA_MASK (0xff << I2CD_RX_DATA_SHIFT) + +#define I2C_HIGHSPEED_RATE 400000 + +#endif /* __AST_I2C_H_ */ -- cgit v1.3.1 From 3b95902d47f89f95242ac143cd2a9ed1fd196157 Mon Sep 17 00:00:00 2001 From: "maxims@google.com" Date: Mon, 17 Apr 2017 12:00:32 -0700 Subject: aspeed: Add support for Clocks needed by MACs Add support for clocks needed by MACs to ast2500 clock driver. The clocks are D2-PLL, which is used by both MACs and PCLK_MAC1 and PCLK_MAC2 for MAC1 and MAC2 respectively. The rate of D2-PLL is hardcoded to 250MHz -- the value used in Aspeed SDK. It is not entirely clear from the datasheet how this clock is used by MACs, so not clear if the rate would ever need to be different. So, for now, hardcoding it is probably safer. The rate of PCLK_MAC{1,2} is chosen based on MAC speed selected through hardware strapping. So, the network driver would only need to enable these clocks, no need to configure the rate. Signed-off-by: Maxim Sloyko Reviewed-by: Simon Glass --- arch/arm/dts/ast2500-u-boot.dtsi | 8 + arch/arm/include/asm/arch-aspeed/scu_ast2500.h | 62 +++++- drivers/clk/aspeed/clk_ast2500.c | 265 ++++++++++++++++++++++--- include/dt-bindings/clock/ast2500-scu.h | 2 + 4 files changed, 304 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/arch/arm/dts/ast2500-u-boot.dtsi b/arch/arm/dts/ast2500-u-boot.dtsi index faeeec1be4d..f826646095f 100644 --- a/arch/arm/dts/ast2500-u-boot.dtsi +++ b/arch/arm/dts/ast2500-u-boot.dtsi @@ -61,3 +61,11 @@ }; }; }; + +&mac0 { + clocks = <&scu PCLK_MAC1>, <&scu PLL_D2PLL>; +}; + +&mac1 { + clocks = <&scu PCLK_MAC2>, <&scu PLL_D2PLL>; +}; diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h index 319d75e05ce..fe877b54304 100644 --- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h +++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h @@ -30,9 +30,36 @@ #define SCU_HPLL_POST_SHIFT 13 #define SCU_HPLL_POST_MASK 0x3f +#define SCU_MACCLK_SHIFT 16 +#define SCU_MACCLK_MASK (7 << SCU_MACCLK_SHIFT) + +#define SCU_MISC2_RGMII_HPLL (1 << 23) +#define SCU_MISC2_RGMII_CLKDIV_SHIFT 20 +#define SCU_MISC2_RGMII_CLKDIV_MASK (3 << SCU_MISC2_RGMII_CLKDIV_SHIFT) +#define SCU_MISC2_RMII_MPLL (1 << 19) +#define SCU_MISC2_RMII_CLKDIV_SHIFT 16 +#define SCU_MISC2_RMII_CLKDIV_MASK (3 << SCU_MISC2_RMII_CLKDIV_SHIFT) #define SCU_MISC2_UARTCLK_SHIFT 24 +#define SCU_MISC_D2PLL_OFF (1 << 4) #define SCU_MISC_UARTCLK_DIV13 (1 << 12) +#define SCU_MISC_GCRT_USB20CLK (1 << 21) + +#define SCU_MICDS_MAC1RGMII_TXDLY_SHIFT 0 +#define SCU_MICDS_MAC1RGMII_TXDLY_MASK (0x3f\ + << SCU_MICDS_MAC1RGMII_TXDLY_SHIFT) +#define SCU_MICDS_MAC2RGMII_TXDLY_SHIFT 6 +#define SCU_MICDS_MAC2RGMII_TXDLY_MASK (0x3f\ + << SCU_MICDS_MAC2RGMII_TXDLY_SHIFT) +#define SCU_MICDS_MAC1RMII_RDLY_SHIFT 12 +#define SCU_MICDS_MAC1RMII_RDLY_MASK (0x3f << SCU_MICDS_MAC1RMII_RDLY_SHIFT) +#define SCU_MICDS_MAC2RMII_RDLY_SHIFT 18 +#define SCU_MICDS_MAC2RMII_RDLY_MASK (0x3f << SCU_MICDS_MAC2RMII_RDLY_SHIFT) +#define SCU_MICDS_MAC1RMII_TXFALL (1 << 24) +#define SCU_MICDS_MAC2RMII_TXFALL (1 << 25) +#define SCU_MICDS_RMII1_RCLKEN (1 << 29) +#define SCU_MICDS_RMII2_RCLKEN (1 << 30) +#define SCU_MICDS_RGMIIPLL (1 << 31) /* * SYSRESET is actually more like a Power register, @@ -71,14 +98,45 @@ */ #define SCU_PIN_FUN_MAC1_MDC (1 << 30) #define SCU_PIN_FUN_MAC1_MDIO (1 << 31) -#define SCU_PIN_FUN_MAC1_PHY_LINK (1 << 0) +#define SCU_PIN_FUN_MAC1_PHY_LINK (1 << 0) #define SCU_PIN_FUN_MAC2_MDIO (1 << 2) -#define SCU_PIN_FUN_MAC2_PHY_LINK (1 << 1) +#define SCU_PIN_FUN_MAC2_PHY_LINK (1 << 1) #define SCU_PIN_FUN_SCL1 (1 << 12) #define SCU_PIN_FUN_SCL2 (1 << 14) #define SCU_PIN_FUN_SDA1 (1 << 13) #define SCU_PIN_FUN_SDA2 (1 << 15) +#define SCU_CLKSTOP_MAC1 (1 << 20) +#define SCU_CLKSTOP_MAC2 (1 << 21) + +#define SCU_D2PLL_EXT1_OFF (1 << 0) +#define SCU_D2PLL_EXT1_BYPASS (1 << 1) +#define SCU_D2PLL_EXT1_RESET (1 << 2) +#define SCU_D2PLL_EXT1_MODE_SHIFT 3 +#define SCU_D2PLL_EXT1_MODE_MASK (3 << SCU_D2PLL_EXT1_MODE_SHIFT) +#define SCU_D2PLL_EXT1_PARAM_SHIFT 5 +#define SCU_D2PLL_EXT1_PARAM_MASK (0x1ff << SCU_D2PLL_EXT1_PARAM_SHIFT) + +#define SCU_D2PLL_NUM_SHIFT 0 +#define SCU_D2PLL_NUM_MASK (0xff << SCU_D2PLL_NUM_SHIFT) +#define SCU_D2PLL_DENUM_SHIFT 8 +#define SCU_D2PLL_DENUM_MASK (0x1f << SCU_D2PLL_DENUM_SHIFT) +#define SCU_D2PLL_POST_SHIFT 13 +#define SCU_D2PLL_POST_MASK (0x3f << SCU_D2PLL_POST_SHIFT) +#define SCU_D2PLL_ODIV_SHIFT 19 +#define SCU_D2PLL_ODIV_MASK (7 << SCU_D2PLL_ODIV_SHIFT) +#define SCU_D2PLL_SIC_SHIFT 22 +#define SCU_D2PLL_SIC_MASK (0x1f << SCU_D2PLL_SIC_SHIFT) +#define SCU_D2PLL_SIP_SHIFT 27 +#define SCU_D2PLL_SIP_MASK (0x1f << SCU_D2PLL_SIP_SHIFT) + +#define SCU_CLKDUTY_DCLK_SHIFT 0 +#define SCU_CLKDUTY_DCLK_MASK (0x3f << SCU_CLKDUTY_DCLK_SHIFT) +#define SCU_CLKDUTY_RGMII1TXCK_SHIFT 8 +#define SCU_CLKDUTY_RGMII1TXCK_MASK (0x7f << SCU_CLKDUTY_RGMII1TXCK_SHIFT) +#define SCU_CLKDUTY_RGMII2TXCK_SHIFT 16 +#define SCU_CLKDUTY_RGMII2TXCK_MASK (0x7f << SCU_CLKDUTY_RGMII2TXCK_SHIFT) + #ifndef __ASSEMBLY__ struct ast2500_clk_priv { diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c index 9e4c66ea85f..7b4b5c64ac7 100644 --- a/drivers/clk/aspeed/clk_ast2500.c +++ b/drivers/clk/aspeed/clk_ast2500.c @@ -12,16 +12,39 @@ #include #include +/* + * MAC Clock Delay settings, taken from Aspeed SDK + */ +#define RGMII_TXCLK_ODLY 8 +#define RMII_RXCLK_IDLY 2 + +/* + * TGMII Clock Duty constants, taken from Aspeed SDK + */ +#define RGMII2_TXCK_DUTY 0x66 +#define RGMII1_TXCK_DUTY 0x64 + +#define D2PLL_DEFAULT_RATE (250 * 1000 * 1000) + DECLARE_GLOBAL_DATA_PTR; /* + * Clock divider/multiplier configuration struct. * For H-PLL and M-PLL the formula is * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1) * M - Numerator * N - Denumerator * P - Post Divider * They have the same layout in their control register. + * + * D-PLL and D2-PLL have extra divider (OD + 1), which is not + * yet needed and ignored by clock configurations. */ +struct ast2500_div_config { + unsigned int num; + unsigned int denum; + unsigned int post_div; +}; /* * Get the rate of the M-PLL clock from input clock frequency and @@ -143,30 +166,41 @@ static ulong ast2500_clk_get_rate(struct clk *clk) return rate; } -static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate) +/* + * @input_rate - the rate of input clock in Hz + * @requested_rate - desired output rate in Hz + * @div - this is an IN/OUT parameter, at input all fields of the config + * need to be set to their maximum allowed values. + * The result (the best config we could find), would also be returned + * in this structure. + * + * @return The clock rate, when the resulting div_config is used. + */ +static ulong ast2500_calc_clock_config(ulong input_rate, ulong requested_rate, + struct ast2500_div_config *cfg) { - ulong clkin = ast2500_get_clkin(scu); - u32 mpll_reg; - /* - * There are not that many combinations of numerator, denumerator - * and post divider, so just brute force the best combination. - * However, to avoid overflow when multiplying, use kHz. + * The assumption is that kHz precision is good enough and + * also enough to avoid overflow when multiplying. */ - const ulong clkin_khz = clkin / 1000; - const ulong rate_khz = rate / 1000; - ulong best_num = 0; - ulong best_denum = 0; - ulong best_post = 0; - ulong delta = rate; - ulong num, denum, post; - - for (denum = 0; denum <= SCU_MPLL_DENUM_MASK; ++denum) { - for (post = 0; post <= SCU_MPLL_POST_MASK; ++post) { - num = (rate_khz * (post + 1) / clkin_khz) * (denum + 1); - ulong new_rate_khz = (clkin_khz - * ((num + 1) / (denum + 1))) - / (post + 1); + const ulong input_rate_khz = input_rate / 1000; + const ulong rate_khz = requested_rate / 1000; + const struct ast2500_div_config max_vals = *cfg; + struct ast2500_div_config it = { 0, 0, 0 }; + ulong delta = rate_khz; + ulong new_rate_khz = 0; + + for (; it.denum <= max_vals.denum; ++it.denum) { + for (it.post_div = 0; it.post_div <= max_vals.post_div; + ++it.post_div) { + it.num = (rate_khz * (it.post_div + 1) / input_rate_khz) + * (it.denum + 1); + if (it.num > max_vals.num) + continue; + + new_rate_khz = (input_rate_khz + * ((it.num + 1) / (it.denum + 1))) + / (it.post_div + 1); /* Keep the rate below requested one. */ if (new_rate_khz > rate_khz) @@ -174,25 +208,35 @@ static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate) if (new_rate_khz - rate_khz < delta) { delta = new_rate_khz - rate_khz; - - best_num = num; - best_denum = denum; - best_post = post; - + *cfg = it; if (delta == 0) - goto rate_calc_done; + return new_rate_khz * 1000; } } } - rate_calc_done: + return new_rate_khz * 1000; +} + +static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate) +{ + ulong clkin = ast2500_get_clkin(scu); + u32 mpll_reg; + struct ast2500_div_config div_cfg = { + .num = SCU_MPLL_NUM_MASK, + .denum = SCU_MPLL_DENUM_MASK, + .post_div = SCU_MPLL_POST_MASK + }; + + ast2500_calc_clock_config(clkin, rate, &div_cfg); + mpll_reg = readl(&scu->m_pll_param); mpll_reg &= ~((SCU_MPLL_POST_MASK << SCU_MPLL_POST_SHIFT) | (SCU_MPLL_NUM_MASK << SCU_MPLL_NUM_SHIFT) | (SCU_MPLL_DENUM_MASK << SCU_MPLL_DENUM_SHIFT)); - mpll_reg |= (best_post << SCU_MPLL_POST_SHIFT) - | (best_num << SCU_MPLL_NUM_SHIFT) - | (best_denum << SCU_MPLL_DENUM_SHIFT); + mpll_reg |= (div_cfg.post_div << SCU_MPLL_POST_SHIFT) + | (div_cfg.num << SCU_MPLL_NUM_SHIFT) + | (div_cfg.denum << SCU_MPLL_DENUM_SHIFT); ast_scu_unlock(scu); writel(mpll_reg, &scu->m_pll_param); @@ -201,6 +245,136 @@ static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate) return ast2500_get_mpll_rate(clkin, mpll_reg); } +static ulong ast2500_configure_mac(struct ast2500_scu *scu, int index) +{ + ulong clkin = ast2500_get_clkin(scu); + ulong hpll_rate = ast2500_get_hpll_rate(clkin, + readl(&scu->h_pll_param)); + ulong required_rate; + u32 hwstrap; + u32 divisor; + u32 reset_bit; + u32 clkstop_bit; + + /* + * According to data sheet, for 10/100 mode the MAC clock frequency + * should be at least 25MHz and for 1000 mode at least 100MHz + */ + hwstrap = readl(&scu->hwstrap); + if (hwstrap & (SCU_HWSTRAP_MAC1_RGMII | SCU_HWSTRAP_MAC2_RGMII)) + required_rate = 100 * 1000 * 1000; + else + required_rate = 25 * 1000 * 1000; + + divisor = hpll_rate / required_rate; + + if (divisor < 4) { + /* Clock can't run fast enough, but let's try anyway */ + debug("MAC clock too slow\n"); + divisor = 4; + } else if (divisor > 16) { + /* Can't slow down the clock enough, but let's try anyway */ + debug("MAC clock too fast\n"); + divisor = 16; + } + + switch (index) { + case 1: + reset_bit = SCU_SYSRESET_MAC1; + clkstop_bit = SCU_CLKSTOP_MAC1; + break; + case 2: + reset_bit = SCU_SYSRESET_MAC2; + clkstop_bit = SCU_CLKSTOP_MAC2; + break; + default: + return -EINVAL; + } + + ast_scu_unlock(scu); + clrsetbits_le32(&scu->clk_sel1, SCU_MACCLK_MASK, + ((divisor - 2) / 2) << SCU_MACCLK_SHIFT); + + /* + * Disable MAC, start its clock and re-enable it. + * The procedure and the delays (100us & 10ms) are + * specified in the datasheet. + */ + setbits_le32(&scu->sysreset_ctrl1, reset_bit); + udelay(100); + clrbits_le32(&scu->clk_stop_ctrl1, clkstop_bit); + mdelay(10); + clrbits_le32(&scu->sysreset_ctrl1, reset_bit); + + writel((RGMII2_TXCK_DUTY << SCU_CLKDUTY_RGMII2TXCK_SHIFT) + | (RGMII1_TXCK_DUTY << SCU_CLKDUTY_RGMII1TXCK_SHIFT), + &scu->clk_duty_sel); + + ast_scu_lock(scu); + + return required_rate; +} + +static ulong ast2500_configure_d2pll(struct ast2500_scu *scu, ulong rate) +{ + /* + * The values and the meaning of the next three + * parameters are undocumented. Taken from Aspeed SDK. + */ + const u32 d2_pll_ext_param = 0x2c; + const u32 d2_pll_sip = 0x11; + const u32 d2_pll_sic = 0x18; + u32 clk_delay_settings = + (RMII_RXCLK_IDLY << SCU_MICDS_MAC1RMII_RDLY_SHIFT) + | (RMII_RXCLK_IDLY << SCU_MICDS_MAC2RMII_RDLY_SHIFT) + | (RGMII_TXCLK_ODLY << SCU_MICDS_MAC1RGMII_TXDLY_SHIFT) + | (RGMII_TXCLK_ODLY << SCU_MICDS_MAC2RGMII_TXDLY_SHIFT); + struct ast2500_div_config div_cfg = { + .num = SCU_D2PLL_NUM_MASK >> SCU_D2PLL_NUM_SHIFT, + .denum = SCU_D2PLL_DENUM_MASK >> SCU_D2PLL_DENUM_SHIFT, + .post_div = SCU_D2PLL_POST_MASK >> SCU_D2PLL_POST_SHIFT, + }; + ulong clkin = ast2500_get_clkin(scu); + ulong new_rate; + + ast_scu_unlock(scu); + writel((d2_pll_ext_param << SCU_D2PLL_EXT1_PARAM_SHIFT) + | SCU_D2PLL_EXT1_OFF + | SCU_D2PLL_EXT1_RESET, &scu->d2_pll_ext_param[0]); + + /* + * Select USB2.0 port1 PHY clock as a clock source for GCRT. + * This would disconnect it from D2-PLL. + */ + clrsetbits_le32(&scu->misc_ctrl1, SCU_MISC_D2PLL_OFF, + SCU_MISC_GCRT_USB20CLK); + + new_rate = ast2500_calc_clock_config(clkin, rate, &div_cfg); + writel((d2_pll_sip << SCU_D2PLL_SIP_SHIFT) + | (d2_pll_sic << SCU_D2PLL_SIC_SHIFT) + | (div_cfg.num << SCU_D2PLL_NUM_SHIFT) + | (div_cfg.denum << SCU_D2PLL_DENUM_SHIFT) + | (div_cfg.post_div << SCU_D2PLL_POST_SHIFT), + &scu->d2_pll_param); + + clrbits_le32(&scu->d2_pll_ext_param[0], + SCU_D2PLL_EXT1_OFF | SCU_D2PLL_EXT1_RESET); + + clrsetbits_le32(&scu->misc_ctrl2, + SCU_MISC2_RGMII_HPLL | SCU_MISC2_RMII_MPLL + | SCU_MISC2_RGMII_CLKDIV_MASK | + SCU_MISC2_RMII_CLKDIV_MASK, + (4 << SCU_MISC2_RMII_CLKDIV_SHIFT)); + + writel(clk_delay_settings | SCU_MICDS_RGMIIPLL, &scu->mac_clk_delay); + writel(clk_delay_settings, &scu->mac_clk_delay_100M); + writel(clk_delay_settings, &scu->mac_clk_delay_10M); + + ast_scu_lock(scu); + + return new_rate; +} + static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate) { struct ast2500_clk_priv *priv = dev_get_priv(clk->dev); @@ -211,6 +385,9 @@ static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate) case MCLK_DDR: new_rate = ast2500_configure_ddr(priv->scu, rate); break; + case PLL_D2PLL: + new_rate = ast2500_configure_d2pll(priv->scu, rate); + break; default: return -ENOENT; } @@ -218,9 +395,35 @@ static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate) return new_rate; } +static int ast2500_clk_enable(struct clk *clk) +{ + struct ast2500_clk_priv *priv = dev_get_priv(clk->dev); + + switch (clk->id) { + /* + * For MAC clocks the clock rate is + * configured based on whether RGMII or RMII mode has been selected + * through hardware strapping. + */ + case PCLK_MAC1: + ast2500_configure_mac(priv->scu, 1); + break; + case PCLK_MAC2: + ast2500_configure_mac(priv->scu, 2); + break; + case PLL_D2PLL: + ast2500_configure_d2pll(priv->scu, D2PLL_DEFAULT_RATE); + default: + return -ENOENT; + } + + return 0; +} + struct clk_ops ast2500_clk_ops = { .get_rate = ast2500_clk_get_rate, .set_rate = ast2500_clk_set_rate, + .enable = ast2500_clk_enable, }; static int ast2500_clk_probe(struct udevice *dev) diff --git a/include/dt-bindings/clock/ast2500-scu.h b/include/dt-bindings/clock/ast2500-scu.h index ca58b12943b..e2d7aaf9fe8 100644 --- a/include/dt-bindings/clock/ast2500-scu.h +++ b/include/dt-bindings/clock/ast2500-scu.h @@ -27,3 +27,5 @@ #define PCLK_UART3 503 #define PCLK_UART4 504 #define PCLK_UART5 505 +#define PCLK_MAC1 506 +#define PCLK_MAC2 507 -- cgit v1.3.1 From defb184904c05df8ca49bd0265969ce72cb92401 Mon Sep 17 00:00:00 2001 From: "maxims@google.com" Date: Mon, 17 Apr 2017 12:00:33 -0700 Subject: aspeed: Refactor SCU to use consistent mask & shift Refactor SCU header to use consistent Mask & Shift values. Now, consistently, to read value from SCU register, mask needs to be applied before shift. Signed-off-by: Maxim Sloyko Reviewed-by: Simon Glass --- arch/arm/include/asm/arch-aspeed/scu_ast2500.h | 12 ++++---- arch/arm/mach-aspeed/ast2500/sdram_ast2500.c | 5 ++-- drivers/clk/aspeed/clk_ast2500.c | 39 +++++++++++++------------- 3 files changed, 27 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h index fe877b54304..590aed2f6c2 100644 --- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h +++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h @@ -8,8 +8,8 @@ #define SCU_UNLOCK_VALUE 0x1688a8a8 -#define SCU_HWSTRAP_VGAMEM_MASK 3 #define SCU_HWSTRAP_VGAMEM_SHIFT 2 +#define SCU_HWSTRAP_VGAMEM_MASK (3 << SCU_HWSTRAP_VGAMEM_SHIFT) #define SCU_HWSTRAP_MAC1_RGMII (1 << 6) #define SCU_HWSTRAP_MAC2_RGMII (1 << 7) #define SCU_HWSTRAP_DDR4 (1 << 24) @@ -18,17 +18,17 @@ #define SCU_MPLL_DENUM_SHIFT 0 #define SCU_MPLL_DENUM_MASK 0x1f #define SCU_MPLL_NUM_SHIFT 5 -#define SCU_MPLL_NUM_MASK 0xff +#define SCU_MPLL_NUM_MASK (0xff << SCU_MPLL_NUM_SHIFT) #define SCU_MPLL_POST_SHIFT 13 -#define SCU_MPLL_POST_MASK 0x3f +#define SCU_MPLL_POST_MASK (0x3f << SCU_MPLL_POST_SHIFT) #define SCU_PCLK_DIV_SHIFT 23 -#define SCU_PCLK_DIV_MASK 7 +#define SCU_PCLK_DIV_MASK (7 << SCU_PCLK_DIV_SHIFT) #define SCU_HPLL_DENUM_SHIFT 0 #define SCU_HPLL_DENUM_MASK 0x1f #define SCU_HPLL_NUM_SHIFT 5 -#define SCU_HPLL_NUM_MASK 0xff +#define SCU_HPLL_NUM_MASK (0xff << SCU_HPLL_NUM_SHIFT) #define SCU_HPLL_POST_SHIFT 13 -#define SCU_HPLL_POST_MASK 0x3f +#define SCU_HPLL_POST_MASK (0x3f << SCU_HPLL_POST_SHIFT) #define SCU_MACCLK_SHIFT 16 #define SCU_MACCLK_MASK (7 << SCU_MACCLK_SHIFT) diff --git a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c index efcf452b178..6383f727f2a 100644 --- a/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c +++ b/arch/arm/mach-aspeed/ast2500/sdram_ast2500.c @@ -183,9 +183,8 @@ static int ast2500_sdrammc_ddr4_calibrate_vref(struct dram_info *info) static size_t ast2500_sdrammc_get_vga_mem_size(struct dram_info *info) { size_t vga_mem_size_base = 8 * 1024 * 1024; - u32 vga_hwconf = (readl(&info->scu->hwstrap) - >> SCU_HWSTRAP_VGAMEM_SHIFT) - & SCU_HWSTRAP_VGAMEM_MASK; + u32 vga_hwconf = (readl(&info->scu->hwstrap) & SCU_HWSTRAP_VGAMEM_MASK) + >> SCU_HWSTRAP_VGAMEM_SHIFT; return vga_mem_size_base << vga_hwconf; } diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c index 7b4b5c64ac7..ccf47a1da11 100644 --- a/drivers/clk/aspeed/clk_ast2500.c +++ b/drivers/clk/aspeed/clk_ast2500.c @@ -52,11 +52,11 @@ struct ast2500_div_config { */ static ulong ast2500_get_mpll_rate(ulong clkin, u32 mpll_reg) { - const ulong num = (mpll_reg >> SCU_MPLL_NUM_SHIFT) & SCU_MPLL_NUM_MASK; - const ulong denum = (mpll_reg >> SCU_MPLL_DENUM_SHIFT) - & SCU_MPLL_DENUM_MASK; - const ulong post_div = (mpll_reg >> SCU_MPLL_POST_SHIFT) - & SCU_MPLL_POST_MASK; + const ulong num = (mpll_reg & SCU_MPLL_NUM_MASK) >> SCU_MPLL_NUM_SHIFT; + const ulong denum = (mpll_reg & SCU_MPLL_DENUM_MASK) + >> SCU_MPLL_DENUM_SHIFT; + const ulong post_div = (mpll_reg & SCU_MPLL_POST_MASK) + >> SCU_MPLL_POST_SHIFT; return (clkin * ((num + 1) / (denum + 1))) / (post_div + 1); } @@ -67,11 +67,11 @@ static ulong ast2500_get_mpll_rate(ulong clkin, u32 mpll_reg) */ static ulong ast2500_get_hpll_rate(ulong clkin, u32 hpll_reg) { - const ulong num = (hpll_reg >> SCU_HPLL_NUM_SHIFT) & SCU_HPLL_NUM_MASK; - const ulong denum = (hpll_reg >> SCU_HPLL_DENUM_SHIFT) - & SCU_HPLL_DENUM_MASK; - const ulong post_div = (hpll_reg >> SCU_HPLL_POST_SHIFT) - & SCU_HPLL_POST_MASK; + const ulong num = (hpll_reg & SCU_HPLL_NUM_MASK) >> SCU_HPLL_NUM_SHIFT; + const ulong denum = (hpll_reg & SCU_HPLL_DENUM_MASK) + >> SCU_HPLL_DENUM_SHIFT; + const ulong post_div = (hpll_reg & SCU_HPLL_POST_MASK) + >> SCU_HPLL_POST_SHIFT; return (clkin * ((num + 1) / (denum + 1))) / (post_div + 1); } @@ -136,11 +136,11 @@ static ulong ast2500_clk_get_rate(struct clk *clk) case BCLK_PCLK: { ulong apb_div = 4 + 4 * ((readl(&priv->scu->clk_sel1) - >> SCU_PCLK_DIV_SHIFT) & - SCU_PCLK_DIV_MASK); + & SCU_PCLK_DIV_MASK) + >> SCU_PCLK_DIV_SHIFT); rate = ast2500_get_hpll_rate(clkin, - readl(&priv->scu-> - h_pll_param)); + readl(&priv-> + scu->h_pll_param)); rate = rate / apb_div; } break; @@ -223,17 +223,16 @@ static ulong ast2500_configure_ddr(struct ast2500_scu *scu, ulong rate) ulong clkin = ast2500_get_clkin(scu); u32 mpll_reg; struct ast2500_div_config div_cfg = { - .num = SCU_MPLL_NUM_MASK, - .denum = SCU_MPLL_DENUM_MASK, - .post_div = SCU_MPLL_POST_MASK + .num = (SCU_MPLL_NUM_MASK >> SCU_MPLL_NUM_SHIFT), + .denum = (SCU_MPLL_DENUM_MASK >> SCU_MPLL_DENUM_SHIFT), + .post_div = (SCU_MPLL_POST_MASK >> SCU_MPLL_POST_SHIFT), }; ast2500_calc_clock_config(clkin, rate, &div_cfg); mpll_reg = readl(&scu->m_pll_param); - mpll_reg &= ~((SCU_MPLL_POST_MASK << SCU_MPLL_POST_SHIFT) - | (SCU_MPLL_NUM_MASK << SCU_MPLL_NUM_SHIFT) - | (SCU_MPLL_DENUM_MASK << SCU_MPLL_DENUM_SHIFT)); + mpll_reg &= ~(SCU_MPLL_POST_MASK | SCU_MPLL_NUM_MASK + | SCU_MPLL_DENUM_MASK); mpll_reg |= (div_cfg.post_div << SCU_MPLL_POST_SHIFT) | (div_cfg.num << SCU_MPLL_NUM_SHIFT) | (div_cfg.denum << SCU_MPLL_DENUM_SHIFT); -- cgit v1.3.1 From 78df5e1ed0b6bf6919339d625abccea405d29167 Mon Sep 17 00:00:00 2001 From: Maxim Sloyko Date: Tue, 9 May 2017 09:08:07 -0400 Subject: dm: Update Simple Watchdog uclass - Remove "probe" function from sandbox wdt driver - Fix include order Fixes: 0753bc2d30d7 ("dm: Simple Watchdog uclass") Signed-off-by: Maxim Sloyko [trini: Create as the delta between v1 (applied) and v2 (should have applied)]. Signed-off-by: Tom Rini --- drivers/watchdog/sandbox_wdt.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/sandbox_wdt.c b/drivers/watchdog/sandbox_wdt.c index 34d90bee7e8..02b57f39865 100644 --- a/drivers/watchdog/sandbox_wdt.c +++ b/drivers/watchdog/sandbox_wdt.c @@ -6,8 +6,8 @@ #include #include -#include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -46,15 +46,6 @@ static int sandbox_wdt_expire_now(struct udevice *dev, ulong flags) return 0; } -static int sandbox_wdt_probe(struct udevice *dev) -{ - struct sandbox_state *state = state_get_current(); - - memset(&state->wdt, 0, sizeof(state->wdt)); - - return 0; -} - static const struct wdt_ops sandbox_wdt_ops = { .start = sandbox_wdt_start, .reset = sandbox_wdt_reset, @@ -72,5 +63,4 @@ U_BOOT_DRIVER(wdt_sandbox) = { .id = UCLASS_WDT, .of_match = sandbox_wdt_ids, .ops = &sandbox_wdt_ops, - .probe = sandbox_wdt_probe, }; -- cgit v1.3.1