diff options
Diffstat (limited to 'drivers')
38 files changed, 792 insertions, 397 deletions
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index f9502b36bac..33f4aa24185 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -27,6 +27,18 @@ config SPL_BLK be partitioned into several areas, called 'partitions' in U-Boot. A filesystem can be placed in each partition. +config TPL_BLK + bool "Support block devices in TPL" + depends on TPL_DM && BLK + default y + help + Enable support for block devices, such as SCSI, MMC and USB + flash sticks. These provide a block-level interface which permits + reading, writing and (in some cases) erasing blocks. Block + devices often have a partition table which allows the device to + be partitioned into several areas, called 'partitions' in U-Boot. + A filesystem can be placed in each partition. + config BLOCK_CACHE bool "Use block device cache" depends on BLK diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 0e80ce94058..055d42f7d4a 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -11,4 +11,4 @@ endif obj-$(CONFIG_IDE) += ide.o obj-$(CONFIG_SANDBOX) += sandbox.o -obj-$(CONFIG_$(SPL_)BLOCK_CACHE) += blkcache.o +obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o diff --git a/drivers/core/device.c b/drivers/core/device.c index feed43c8c3e..5176aa3f866 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -331,7 +331,8 @@ int device_probe(struct udevice *dev) /* Allocate private data if requested and not reentered */ size = dev->uclass->uc_drv->per_device_auto_alloc_size; if (size && !dev->uclass_priv) { - dev->uclass_priv = calloc(1, size); + dev->uclass_priv = alloc_priv(size, + dev->uclass->uc_drv->flags); if (!dev->uclass_priv) { ret = -ENOMEM; goto fail; @@ -441,7 +442,7 @@ fail: return ret; } -void *dev_get_platdata(struct udevice *dev) +void *dev_get_platdata(const struct udevice *dev) { if (!dev) { dm_warn("%s: null device\n", __func__); @@ -451,7 +452,7 @@ void *dev_get_platdata(struct udevice *dev) return dev->platdata; } -void *dev_get_parent_platdata(struct udevice *dev) +void *dev_get_parent_platdata(const struct udevice *dev) { if (!dev) { dm_warn("%s: null device\n", __func__); @@ -461,7 +462,7 @@ void *dev_get_parent_platdata(struct udevice *dev) return dev->parent_platdata; } -void *dev_get_uclass_platdata(struct udevice *dev) +void *dev_get_uclass_platdata(const struct udevice *dev) { if (!dev) { dm_warn("%s: null device\n", __func__); @@ -471,7 +472,7 @@ void *dev_get_uclass_platdata(struct udevice *dev) return dev->uclass_platdata; } -void *dev_get_priv(struct udevice *dev) +void *dev_get_priv(const struct udevice *dev) { if (!dev) { dm_warn("%s: null device\n", __func__); @@ -481,7 +482,7 @@ void *dev_get_priv(struct udevice *dev) return dev->priv; } -void *dev_get_uclass_priv(struct udevice *dev) +void *dev_get_uclass_priv(const struct udevice *dev) { if (!dev) { dm_warn("%s: null device\n", __func__); @@ -491,7 +492,7 @@ void *dev_get_uclass_priv(struct udevice *dev) return dev->uclass_priv; } -void *dev_get_parent_priv(struct udevice *dev) +void *dev_get_parent_priv(const struct udevice *dev) { if (!dev) { dm_warn("%s: null device\n", __func__); @@ -680,17 +681,35 @@ int device_find_next_child(struct udevice **devp) return 0; } -struct udevice *dev_get_parent(struct udevice *child) +int device_find_first_inactive_child(struct udevice *parent, + enum uclass_id uclass_id, + struct udevice **devp) +{ + struct udevice *dev; + + *devp = NULL; + list_for_each_entry(dev, &parent->child_head, sibling_node) { + if (!device_active(dev) && + device_get_uclass_id(dev) == uclass_id) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + +struct udevice *dev_get_parent(const struct udevice *child) { return child->parent; } -ulong dev_get_driver_data(struct udevice *dev) +ulong dev_get_driver_data(const struct udevice *dev) { return dev->driver_data; } -const void *dev_get_driver_ops(struct udevice *dev) +const void *dev_get_driver_ops(const struct udevice *dev) { if (!dev || !dev->driver->ops) return NULL; @@ -698,12 +717,12 @@ const void *dev_get_driver_ops(struct udevice *dev) return dev->driver->ops; } -enum uclass_id device_get_uclass_id(struct udevice *dev) +enum uclass_id device_get_uclass_id(const struct udevice *dev) { return dev->uclass->uc_drv->id; } -const char *dev_get_uclass_name(struct udevice *dev) +const char *dev_get_uclass_name(const struct udevice *dev) { if (!dev) return NULL; @@ -711,7 +730,7 @@ const char *dev_get_uclass_name(struct udevice *dev) return dev->uclass->uc_drv->name; } -bool device_has_children(struct udevice *dev) +bool device_has_children(const struct udevice *dev) { return !list_empty(&dev->child_head); } diff --git a/drivers/core/of_extra.c b/drivers/core/of_extra.c index aa48917dddf..f1f393c3598 100644 --- a/drivers/core/of_extra.c +++ b/drivers/core/of_extra.c @@ -13,19 +13,30 @@ int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry) { const char *prop; - u32 reg[2]; - if (ofnode_read_u32_array(node, "reg", reg, 2)) { - debug("Node '%s' has bad/missing 'reg' property\n", + if (ofnode_read_u32(node, "image-pos", &entry->offset)) { + debug("Node '%s' has bad/missing 'image-pos' property\n", ofnode_get_name(node)); - return -log_ret(ENOENT); + return log_ret(-ENOENT); + } + if (ofnode_read_u32(node, "size", &entry->length)) { + debug("Node '%s' has bad/missing 'size' property\n", + ofnode_get_name(node)); + return log_ret(-ENOENT); } - entry->offset = reg[0]; - entry->length = reg[1]; entry->used = ofnode_read_s32_default(node, "used", entry->length); prop = ofnode_read_string(node, "compress"); - entry->compress_algo = prop && !strcmp(prop, "lzo") ? - FMAP_COMPRESS_LZO : FMAP_COMPRESS_NONE; + if (prop) { + if (!strcmp(prop, "lz4")) + entry->compress_algo = FMAP_COMPRESS_LZ4; + else + return log_msg_ret("Unknown compression algo", + -EINVAL); + } else { + entry->compress_algo = FMAP_COMPRESS_NONE; + } + entry->unc_length = ofnode_read_s32_default(node, "uncomp-size", + entry->length); prop = ofnode_read_string(node, "hash"); if (prop) entry->hash_size = strlen(prop); diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 1e354803b06..b7b7ad3a625 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -541,9 +541,13 @@ fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property, if (!prop) return FDT_ADDR_T_NONE; na = of_n_addr_cells(np); - ns = of_n_addr_cells(np); + ns = of_n_size_cells(np); *sizep = of_read_number(prop + na, ns); - return of_read_number(prop, na); + + if (IS_ENABLED(CONFIG_OF_TRANSLATE) && ns > 0) + return of_translate_address(np, prop); + else + return of_read_number(prop, na); } else { return fdtdec_get_addr_size(gd->fdt_blob, ofnode_to_offset(node), property, @@ -695,6 +699,8 @@ bool ofnode_pre_reloc(ofnode node) { if (ofnode_read_bool(node, "u-boot,dm-pre-reloc")) return true; + if (ofnode_read_bool(node, "u-boot,dm-pre-proper")) + return true; #ifdef CONFIG_TPL_BUILD if (ofnode_read_bool(node, "u-boot,dm-tpl")) diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 7ffb949f12d..7afdafed948 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -1,3 +1,16 @@ +config INPUT + bool "Enable input subsystem" + depends on DM + default y + +config SPL_INPUT + bool "Enable input subsystem for SPL" + depends on SPL_DM + +config TPL_INPUT + bool "Enable input subsystem for TPL" + depends on TPL_DM + config DM_KEYBOARD bool "Enable driver model keyboard support" depends on DM @@ -7,8 +20,43 @@ config DM_KEYBOARD includes methods to start/stop the device, check for available input and update LEDs if the keyboard has them. +config SPL_DM_KEYBOARD + bool "Enable driver model keyboard support" + depends on SPL_DM + help + This adds a uclass for keyboards and implements keyboard support + using driver model. The API is implemented by keyboard.h and + includes methods to start/stop the device, check for available + input and update LEDs if the keyboard has them. + +config TPL_DM_KEYBOARD + bool "Enable driver model keyboard support" + depends on TPL_DM + help + This adds a uclass for keyboards and implements keyboard support + using driver model. The API is implemented by keyboard.h and + includes methods to start/stop the device, check for available + input and update LEDs if the keyboard has them. + config CROS_EC_KEYB bool "Enable Chrome OS EC keyboard support" + depends on INPUT + help + Most ARM Chromebooks use an EC to provide access to the keyboard. + Messages are used to request key scans from the EC and these are + then decoded into keys by this driver. + +config SPL_CROS_EC_KEYB + bool "Enable Chrome OS EC keyboard support in SPL" + depends on SPL_INPUT + help + Most ARM Chromebooks use an EC to provide access to the keyboard. + Messages are used to request key scans from the EC and these are + then decoded into keys by this driver. + +config TPL_CROS_EC_KEYB + bool "Enable Chrome OS EC keyboard support in TPL" + depends on TPL_INPUT help Most ARM Chromebooks use an EC to provide access to the keyboard. Messages are used to request key scans from the EC and these are diff --git a/drivers/input/Makefile b/drivers/input/Makefile index d13baf3576a..fd56d7b3492 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -3,12 +3,15 @@ # (C) Copyright 2000-2007 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. -obj-$(CONFIG_DM_KEYBOARD) += keyboard-uclass.o +obj-y += input.o +obj-$(CONFIG_$(SPL_TPL_)CROS_EC_KEYB) += cros_ec_keyb.o +obj-$(CONFIG_$(SPL_TPL_)OF_CONTROL) += key_matrix.o +obj-$(CONFIG_$(SPL_TPL_)DM_KEYBOARD) += keyboard-uclass.o + +ifndef CONFIG_SPL_BUILD obj-$(CONFIG_I8042_KEYB) += i8042.o obj-$(CONFIG_TEGRA_KEYBOARD) += tegra-kbc.o obj-$(CONFIG_TWL4030_INPUT) += twl4030.o obj-$(CONFIG_TWL6030_INPUT) += twl6030.o -obj-$(CONFIG_CROS_EC_KEYB) += cros_ec_keyb.o -obj-y += input.o -obj-$(CONFIG_$(SPL_)OF_CONTROL) += key_matrix.o +endif diff --git a/drivers/input/input.c b/drivers/input/input.c index 29620a9e279..4f514dba56d 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -652,7 +652,7 @@ int input_stdio_register(struct stdio_dev *dev) int error; error = stdio_register(dev); - +#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(ENV_SUPPORT) /* check if this is the standard input device */ if (!error && strcmp(env_get("stdin"), dev->name) == 0) { /* reassign the console */ @@ -660,6 +660,9 @@ int input_stdio_register(struct stdio_dev *dev) console_assign(stdin, dev->name)) return -1; } +#else + error = error; +#endif return 0; } diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 6f299d407a4..190505c11c7 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -83,15 +83,15 @@ int cros_ec_calc_checksum(const uint8_t *data, int size) * @param dout_len Size of output data in bytes * @return packet size in bytes, or <0 if error. */ -static int create_proto3_request(struct cros_ec_dev *dev, +static int create_proto3_request(struct cros_ec_dev *cdev, int cmd, int cmd_version, const void *dout, int dout_len) { - struct ec_host_request *rq = (struct ec_host_request *)dev->dout; + struct ec_host_request *rq = (struct ec_host_request *)cdev->dout; int out_bytes = dout_len + sizeof(*rq); /* Fail if output size is too big */ - if (out_bytes > (int)sizeof(dev->dout)) { + if (out_bytes > (int)sizeof(cdev->dout)) { debug("%s: Cannot send %d bytes\n", __func__, dout_len); return -EC_RES_REQUEST_TRUNCATED; } @@ -108,9 +108,9 @@ static int create_proto3_request(struct cros_ec_dev *dev, memcpy(rq + 1, dout, dout_len); /* Write checksum field so the entire packet sums to 0 */ - rq->checksum = (uint8_t)(-cros_ec_calc_checksum(dev->dout, out_bytes)); + rq->checksum = (uint8_t)(-cros_ec_calc_checksum(cdev->dout, out_bytes)); - cros_ec_dump_data("out", cmd, dev->dout, out_bytes); + cros_ec_dump_data("out", cmd, cdev->dout, out_bytes); /* Return size of request packet */ return out_bytes; @@ -123,12 +123,12 @@ static int create_proto3_request(struct cros_ec_dev *dev, * @param din_len Maximum size of response in bytes * @return maximum expected number of bytes in response, or <0 if error. */ -static int prepare_proto3_response_buffer(struct cros_ec_dev *dev, int din_len) +static int prepare_proto3_response_buffer(struct cros_ec_dev *cdev, int din_len) { int in_bytes = din_len + sizeof(struct ec_host_response); /* Fail if input size is too big */ - if (in_bytes > (int)sizeof(dev->din)) { + if (in_bytes > (int)sizeof(cdev->din)) { debug("%s: Cannot receive %d bytes\n", __func__, din_len); return -EC_RES_RESPONSE_TOO_BIG; } @@ -197,7 +197,7 @@ static int handle_proto3_response(struct cros_ec_dev *dev, return rs->data_len; } -static int send_command_proto3(struct cros_ec_dev *dev, +static int send_command_proto3(struct cros_ec_dev *cdev, int cmd, int cmd_version, const void *dout, int dout_len, uint8_t **dinp, int din_len) @@ -207,23 +207,24 @@ static int send_command_proto3(struct cros_ec_dev *dev, int rv; /* Create request packet */ - out_bytes = create_proto3_request(dev, cmd, cmd_version, + out_bytes = create_proto3_request(cdev, cmd, cmd_version, dout, dout_len); if (out_bytes < 0) return out_bytes; /* Prepare response buffer */ - in_bytes = prepare_proto3_response_buffer(dev, din_len); + in_bytes = prepare_proto3_response_buffer(cdev, din_len); if (in_bytes < 0) return in_bytes; - ops = dm_cros_ec_get_ops(dev->dev); - rv = ops->packet ? ops->packet(dev->dev, out_bytes, in_bytes) : -ENOSYS; + ops = dm_cros_ec_get_ops(cdev->dev); + rv = ops->packet ? ops->packet(cdev->dev, out_bytes, in_bytes) : + -ENOSYS; if (rv < 0) return rv; /* Process the response */ - return handle_proto3_response(dev, dinp, din_len); + return handle_proto3_response(cdev, dinp, din_len); } static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, @@ -262,15 +263,16 @@ static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, * @param din_len Maximum size of response in bytes * @return number of bytes in response, or -ve on error */ -static int ec_command_inptr(struct cros_ec_dev *dev, uint8_t cmd, - int cmd_version, const void *dout, int dout_len, uint8_t **dinp, - int din_len) +static int ec_command_inptr(struct udevice *dev, uint8_t cmd, + int cmd_version, const void *dout, int dout_len, + uint8_t **dinp, int din_len) { + struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); uint8_t *din = NULL; int len; - len = send_command(dev, cmd, cmd_version, dout, dout_len, - &din, din_len); + len = send_command(cdev, cmd, cmd_version, dout, dout_len, &din, + din_len); /* If the command doesn't complete, wait a while */ if (len == -EC_RES_IN_PROGRESS) { @@ -283,9 +285,9 @@ static int ec_command_inptr(struct cros_ec_dev *dev, uint8_t cmd, int ret; mdelay(50); /* Insert some reasonable delay */ - ret = send_command(dev, EC_CMD_GET_COMMS_STATUS, 0, - NULL, 0, - (uint8_t **)&resp, sizeof(*resp)); + ret = send_command(cdev, EC_CMD_GET_COMMS_STATUS, 0, + NULL, 0, + (uint8_t **)&resp, sizeof(*resp)); if (ret < 0) return ret; @@ -298,8 +300,8 @@ static int ec_command_inptr(struct cros_ec_dev *dev, uint8_t cmd, /* OK it completed, so read the status response */ /* not sure why it was 0 for the last argument */ - len = send_command(dev, EC_CMD_RESEND_RESPONSE, 0, - NULL, 0, &din, din_len); + len = send_command(cdev, EC_CMD_RESEND_RESPONSE, 0, NULL, 0, + &din, din_len); } debug("%s: len=%d, din=%p\n", __func__, len, din); @@ -328,7 +330,7 @@ static int ec_command_inptr(struct cros_ec_dev *dev, uint8_t cmd, * @param din_len Maximum size of response in bytes * @return number of bytes in response, or -ve on error */ -static int ec_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, +static int ec_command(struct udevice *dev, uint8_t cmd, int cmd_version, const void *dout, int dout_len, void *din, int din_len) { @@ -337,7 +339,7 @@ static int ec_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, assert((din_len == 0) || din); len = ec_command_inptr(dev, cmd, cmd_version, dout, dout_len, - &in_buffer, din_len); + &in_buffer, din_len); if (len > 0) { /* * If we were asked to put it somewhere, do so, otherwise just @@ -353,16 +355,14 @@ static int ec_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, int cros_ec_scan_keyboard(struct udevice *dev, struct mbkp_keyscan *scan) { - struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); - - if (ec_command(cdev, EC_CMD_MKBP_STATE, 0, NULL, 0, scan, + if (ec_command(dev, EC_CMD_MKBP_STATE, 0, NULL, 0, scan, sizeof(scan->data)) != sizeof(scan->data)) return -1; return 0; } -int cros_ec_read_id(struct cros_ec_dev *dev, char *id, int maxlen) +int cros_ec_read_id(struct udevice *dev, char *id, int maxlen) { struct ec_response_get_version *r; @@ -388,8 +388,8 @@ int cros_ec_read_id(struct cros_ec_dev *dev, char *id, int maxlen) return 0; } -int cros_ec_read_version(struct cros_ec_dev *dev, - struct ec_response_get_version **versionp) +int cros_ec_read_version(struct udevice *dev, + struct ec_response_get_version **versionp) { if (ec_command_inptr(dev, EC_CMD_GET_VERSION, 0, NULL, 0, (uint8_t **)versionp, sizeof(**versionp)) @@ -399,7 +399,7 @@ int cros_ec_read_version(struct cros_ec_dev *dev, return 0; } -int cros_ec_read_build_info(struct cros_ec_dev *dev, char **strp) +int cros_ec_read_build_info(struct udevice *dev, char **strp) { if (ec_command_inptr(dev, EC_CMD_GET_BUILD_INFO, 0, NULL, 0, (uint8_t **)strp, EC_PROTO2_MAX_PARAM_SIZE) < 0) @@ -408,8 +408,8 @@ int cros_ec_read_build_info(struct cros_ec_dev *dev, char **strp) return 0; } -int cros_ec_read_current_image(struct cros_ec_dev *dev, - enum ec_current_image *image) +int cros_ec_read_current_image(struct udevice *dev, + enum ec_current_image *image) { struct ec_response_get_version *r; @@ -421,8 +421,8 @@ int cros_ec_read_current_image(struct cros_ec_dev *dev, return 0; } -static int cros_ec_wait_on_hash_done(struct cros_ec_dev *dev, - struct ec_response_vboot_hash *hash) +static int cros_ec_wait_on_hash_done(struct udevice *dev, + struct ec_response_vboot_hash *hash) { struct ec_params_vboot_hash p; ulong start; @@ -444,14 +444,14 @@ static int cros_ec_wait_on_hash_done(struct cros_ec_dev *dev, return 0; } - -int cros_ec_read_hash(struct cros_ec_dev *dev, - struct ec_response_vboot_hash *hash) +int cros_ec_read_hash(struct udevice *dev, uint hash_offset, + struct ec_response_vboot_hash *hash) { struct ec_params_vboot_hash p; int rv; p.cmd = EC_VBOOT_HASH_GET; + p.offset = hash_offset; if (ec_command(dev, EC_CMD_VBOOT_HASH, 0, &p, sizeof(p), hash, sizeof(*hash)) < 0) return -1; @@ -474,7 +474,7 @@ int cros_ec_read_hash(struct cros_ec_dev *dev, p.cmd = EC_VBOOT_HASH_START; p.hash_type = EC_VBOOT_HASH_TYPE_SHA256; p.nonce_size = 0; - p.offset = EC_VBOOT_HASH_OFFSET_RW; + p.offset = hash_offset; if (ec_command(dev, EC_CMD_VBOOT_HASH, 0, &p, sizeof(p), hash, sizeof(*hash)) < 0) @@ -489,7 +489,7 @@ int cros_ec_read_hash(struct cros_ec_dev *dev, return 0; } -static int cros_ec_invalidate_hash(struct cros_ec_dev *dev) +static int cros_ec_invalidate_hash(struct udevice *dev) { struct ec_params_vboot_hash p; struct ec_response_vboot_hash *hash; @@ -514,8 +514,7 @@ static int cros_ec_invalidate_hash(struct cros_ec_dev *dev) return 0; } -int cros_ec_reboot(struct cros_ec_dev *dev, enum ec_reboot_cmd cmd, - uint8_t flags) +int cros_ec_reboot(struct udevice *dev, enum ec_reboot_cmd cmd, uint8_t flags) { struct ec_params_reboot_ec p; @@ -555,7 +554,7 @@ int cros_ec_interrupt_pending(struct udevice *dev) return dm_gpio_get_value(&cdev->ec_int); } -int cros_ec_info(struct cros_ec_dev *dev, struct ec_response_mkbp_info *info) +int cros_ec_info(struct udevice *dev, struct ec_response_mkbp_info *info) { if (ec_command(dev, EC_CMD_MKBP_INFO, 0, NULL, 0, info, sizeof(*info)) != sizeof(*info)) @@ -564,7 +563,7 @@ int cros_ec_info(struct cros_ec_dev *dev, struct ec_response_mkbp_info *info) return 0; } -int cros_ec_get_host_events(struct cros_ec_dev *dev, uint32_t *events_ptr) +int cros_ec_get_host_events(struct udevice *dev, uint32_t *events_ptr) { struct ec_response_host_event_mask *resp; @@ -583,7 +582,7 @@ int cros_ec_get_host_events(struct cros_ec_dev *dev, uint32_t *events_ptr) return 0; } -int cros_ec_clear_host_events(struct cros_ec_dev *dev, uint32_t events) +int cros_ec_clear_host_events(struct udevice *dev, uint32_t events) { struct ec_params_host_event_mask params; @@ -600,9 +599,9 @@ int cros_ec_clear_host_events(struct cros_ec_dev *dev, uint32_t events) return 0; } -int cros_ec_flash_protect(struct cros_ec_dev *dev, - uint32_t set_mask, uint32_t set_flags, - struct ec_response_flash_protect *resp) +int cros_ec_flash_protect(struct udevice *dev, uint32_t set_mask, + uint32_t set_flags, + struct ec_response_flash_protect *resp) { struct ec_params_flash_protect params; @@ -617,17 +616,18 @@ int cros_ec_flash_protect(struct cros_ec_dev *dev, return 0; } -static int cros_ec_check_version(struct cros_ec_dev *dev) +static int cros_ec_check_version(struct udevice *dev) { + struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); struct ec_params_hello req; struct ec_response_hello *resp; struct dm_cros_ec_ops *ops; int ret; - ops = dm_cros_ec_get_ops(dev->dev); + ops = dm_cros_ec_get_ops(dev); if (ops->check_version) { - ret = ops->check_version(dev->dev); + ret = ops->check_version(dev); if (ret) return ret; } @@ -647,7 +647,7 @@ static int cros_ec_check_version(struct cros_ec_dev *dev) */ /* Try sending a version 3 packet */ - dev->protocol_version = 3; + cdev->protocol_version = 3; req.in_data = 0; if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req), (uint8_t **)&resp, sizeof(*resp)) > 0) { @@ -655,9 +655,9 @@ static int cros_ec_check_version(struct cros_ec_dev *dev) } /* Try sending a version 2 packet */ - dev->protocol_version = 2; + cdev->protocol_version = 2; if (ec_command_inptr(dev, EC_CMD_HELLO, 0, &req, sizeof(req), - (uint8_t **)&resp, sizeof(*resp)) > 0) { + (uint8_t **)&resp, sizeof(*resp)) > 0) { return 0; } @@ -667,12 +667,12 @@ static int cros_ec_check_version(struct cros_ec_dev *dev) * version is no longer supported, and we don't know about any new * protocol versions. */ - dev->protocol_version = 0; + cdev->protocol_version = 0; printf("%s: ERROR: old EC interface not supported\n", __func__); return -1; } -int cros_ec_test(struct cros_ec_dev *dev) +int cros_ec_test(struct udevice *dev) { struct ec_params_hello req; struct ec_response_hello *resp; @@ -691,7 +691,7 @@ int cros_ec_test(struct cros_ec_dev *dev) return 0; } -int cros_ec_flash_offset(struct cros_ec_dev *dev, enum ec_flash_region region, +int cros_ec_flash_offset(struct udevice *dev, enum ec_flash_region region, uint32_t *offset, uint32_t *size) { struct ec_params_flash_region_info p; @@ -713,7 +713,7 @@ int cros_ec_flash_offset(struct cros_ec_dev *dev, enum ec_flash_region region, return 0; } -int cros_ec_flash_erase(struct cros_ec_dev *dev, uint32_t offset, uint32_t size) +int cros_ec_flash_erase(struct udevice *dev, uint32_t offset, uint32_t size) { struct ec_params_flash_erase p; @@ -741,8 +741,8 @@ int cros_ec_flash_erase(struct cros_ec_dev *dev, uint32_t offset, uint32_t size) * @param size Number of bytes to write * @return 0 if ok, -1 on error */ -static int cros_ec_flash_write_block(struct cros_ec_dev *dev, - const uint8_t *data, uint32_t offset, uint32_t size) +static int cros_ec_flash_write_block(struct udevice *dev, const uint8_t *data, + uint32_t offset, uint32_t size) { struct ec_params_flash_write *p; int ret; @@ -767,7 +767,7 @@ static int cros_ec_flash_write_block(struct cros_ec_dev *dev, /** * Return optimal flash write burst size */ -static int cros_ec_flash_write_burst_size(struct cros_ec_dev *dev) +static int cros_ec_flash_write_burst_size(struct udevice *dev) { return EC_FLASH_WRITE_VER0_SIZE; } @@ -801,8 +801,8 @@ static int cros_ec_data_is_erased(const uint32_t *data, int size) * @param dev Pointer to device * @param info Pointer to output flash info struct */ -int cros_ec_read_flashinfo(struct cros_ec_dev *dev, - struct ec_response_flash_info *info) +int cros_ec_read_flashinfo(struct udevice *dev, + struct ec_response_flash_info *info) { int ret; @@ -814,9 +814,10 @@ int cros_ec_read_flashinfo(struct cros_ec_dev *dev, return ret < sizeof(*info) ? -1 : 0; } -int cros_ec_flash_write(struct cros_ec_dev *dev, const uint8_t *data, - uint32_t offset, uint32_t size) +int cros_ec_flash_write(struct udevice *dev, const uint8_t *data, + uint32_t offset, uint32_t size) { + struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); uint32_t burst = cros_ec_flash_write_burst_size(dev); uint32_t end, off; int ret; @@ -831,8 +832,8 @@ int cros_ec_flash_write(struct cros_ec_dev *dev, const uint8_t *data, /* If the data is empty, there is no point in programming it */ todo = min(end - off, burst); - if (dev->optimise_flash_write && - cros_ec_data_is_erased((uint32_t *)data, todo)) + if (cdev->optimise_flash_write && + cros_ec_data_is_erased((uint32_t *)data, todo)) continue; ret = cros_ec_flash_write_block(dev, data, off, todo); @@ -858,8 +859,8 @@ int cros_ec_flash_write(struct cros_ec_dev *dev, const uint8_t *data, * @param size Number of bytes to read * @return 0 if ok, -1 on error */ -static int cros_ec_flash_read_block(struct cros_ec_dev *dev, uint8_t *data, - uint32_t offset, uint32_t size) +static int cros_ec_flash_read_block(struct udevice *dev, uint8_t *data, + uint32_t offset, uint32_t size) { struct ec_params_flash_read p; @@ -870,8 +871,8 @@ static int cros_ec_flash_read_block(struct cros_ec_dev *dev, uint8_t *data, &p, sizeof(p), data, size) >= 0 ? 0 : -1; } -int cros_ec_flash_read(struct cros_ec_dev *dev, uint8_t *data, uint32_t offset, - uint32_t size) +int cros_ec_flash_read(struct udevice *dev, uint8_t *data, uint32_t offset, + uint32_t size) { uint32_t burst = cros_ec_flash_write_burst_size(dev); uint32_t end, off; @@ -888,13 +889,14 @@ int cros_ec_flash_read(struct cros_ec_dev *dev, uint8_t *data, uint32_t offset, return 0; } -int cros_ec_flash_update_rw(struct cros_ec_dev *dev, - const uint8_t *image, int image_size) +int cros_ec_flash_update_rw(struct udevice *dev, const uint8_t *image, + int image_size) { uint32_t rw_offset, rw_size; int ret; - if (cros_ec_flash_offset(dev, EC_FLASH_REGION_RW, &rw_offset, &rw_size)) + if (cros_ec_flash_offset(dev, EC_FLASH_REGION_ACTIVE, &rw_offset, + &rw_size)) return -1; if (image_size > (int)rw_size) return -1; @@ -927,26 +929,31 @@ int cros_ec_flash_update_rw(struct cros_ec_dev *dev, return 0; } -int cros_ec_read_vbnvcontext(struct cros_ec_dev *dev, uint8_t *block) +int cros_ec_read_nvdata(struct udevice *dev, uint8_t *block, int size) { struct ec_params_vbnvcontext p; int len; + if (size != EC_VBNV_BLOCK_SIZE) + return -EINVAL; + p.op = EC_VBNV_CONTEXT_OP_READ; len = ec_command(dev, EC_CMD_VBNV_CONTEXT, EC_VER_VBNV_CONTEXT, &p, sizeof(p), block, EC_VBNV_BLOCK_SIZE); if (len < EC_VBNV_BLOCK_SIZE) - return -1; + return -EIO; return 0; } -int cros_ec_write_vbnvcontext(struct cros_ec_dev *dev, const uint8_t *block) +int cros_ec_write_nvdata(struct udevice *dev, const uint8_t *block, int size) { struct ec_params_vbnvcontext p; int len; + if (size != EC_VBNV_BLOCK_SIZE) + return -EINVAL; p.op = EC_VBNV_CONTEXT_OP_WRITE; memcpy(p.block, block, sizeof(p.block)); @@ -960,13 +967,12 @@ int cros_ec_write_vbnvcontext(struct cros_ec_dev *dev, const uint8_t *block) int cros_ec_set_ldo(struct udevice *dev, uint8_t index, uint8_t state) { - struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); struct ec_params_ldo_set params; params.index = index; params.state = state; - if (ec_command_inptr(cdev, EC_CMD_LDO_SET, 0, ¶ms, sizeof(params), + if (ec_command_inptr(dev, EC_CMD_LDO_SET, 0, ¶ms, sizeof(params), NULL, 0)) return -1; @@ -975,13 +981,12 @@ int cros_ec_set_ldo(struct udevice *dev, uint8_t index, uint8_t state) int cros_ec_get_ldo(struct udevice *dev, uint8_t index, uint8_t *state) { - struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); struct ec_params_ldo_get params; struct ec_response_ldo_get *resp; params.index = index; - if (ec_command_inptr(cdev, EC_CMD_LDO_GET, 0, ¶ms, sizeof(params), + if (ec_command_inptr(dev, EC_CMD_LDO_GET, 0, ¶ms, sizeof(params), (uint8_t **)&resp, sizeof(*resp)) != sizeof(*resp)) return -1; @@ -1001,12 +1006,12 @@ int cros_ec_register(struct udevice *dev) GPIOD_IS_IN); cdev->optimise_flash_write = dev_read_bool(dev, "optimise-flash-write"); - if (cros_ec_check_version(cdev)) { + if (cros_ec_check_version(dev)) { debug("%s: Could not detect CROS-EC version\n", __func__); return -CROS_EC_ERR_CHECK_VERSION; } - if (cros_ec_read_id(cdev, id, sizeof(id))) { + if (cros_ec_read_id(dev, id, sizeof(id))) { debug("%s: Could not read KBC ID\n", __func__); return -CROS_EC_ERR_READ_ID; } @@ -1042,7 +1047,7 @@ int cros_ec_decode_ec_flash(struct udevice *dev, struct fdt_cros_ec *config) if (0 == strcmp(name, "ro")) { region = EC_FLASH_REGION_RO; } else if (0 == strcmp(name, "rw")) { - region = EC_FLASH_REGION_RW; + region = EC_FLASH_REGION_ACTIVE; } else if (0 == strcmp(name, "wp-ro")) { region = EC_FLASH_REGION_WP_RO; } else { @@ -1062,7 +1067,6 @@ int cros_ec_decode_ec_flash(struct udevice *dev, struct fdt_cros_ec *config) int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *in, int nmsgs) { - struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); union { struct ec_params_i2c_passthru p; uint8_t outbuf[EC_PROTO2_MAX_PARAM_SIZE]; @@ -1112,7 +1116,7 @@ int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *in, } } - rv = ec_command(cdev, EC_CMD_I2C_PASSTHRU, 0, p, pdata - (uint8_t *)p, + rv = ec_command(dev, EC_CMD_I2C_PASSTHRU, 0, p, pdata - (uint8_t *)p, r, sizeof(*r) + read_len); if (rv < 0) return rv; diff --git a/drivers/misc/cros_ec_lpc.c b/drivers/misc/cros_ec_lpc.c index be17adcc5ac..71d03bfba2b 100644 --- a/drivers/misc/cros_ec_lpc.c +++ b/drivers/misc/cros_ec_lpc.c @@ -40,6 +40,38 @@ static int wait_for_sync(struct cros_ec_dev *dev) return 0; } +int cros_ec_lpc_packet(struct udevice *udev, int out_bytes, int in_bytes) +{ + struct cros_ec_dev *dev = dev_get_uclass_priv(udev); + uint8_t *d; + int i; + + if (out_bytes > EC_LPC_HOST_PACKET_SIZE) + return log_msg_ret("Cannot send that many bytes\n", -E2BIG); + + if (in_bytes > EC_LPC_HOST_PACKET_SIZE) + return log_msg_ret("Cannot receive that many bytes\n", -E2BIG); + + if (wait_for_sync(dev)) + return log_msg_ret("Timeout waiting ready\n", -ETIMEDOUT); + + /* Write data */ + for (i = 0, d = (uint8_t *)dev->dout; i < out_bytes; i++, d++) + outb(*d, EC_LPC_ADDR_HOST_PACKET + i); + + /* Start the command */ + outb(EC_COMMAND_PROTOCOL_3, EC_LPC_ADDR_HOST_CMD); + + if (wait_for_sync(dev)) + return log_msg_ret("Timeout waiting ready\n", -ETIMEDOUT); + + /* Read back args */ + for (i = 0, d = dev->din; i < in_bytes; i++, d++) + *d = inb(EC_LPC_ADDR_HOST_PACKET + i); + + return in_bytes; +} + int cros_ec_lpc_command(struct udevice *udev, uint8_t cmd, int cmd_version, const uint8_t *dout, int dout_len, uint8_t **dinp, int din_len) @@ -200,6 +232,7 @@ static int cros_ec_probe(struct udevice *dev) } static struct dm_cros_ec_ops cros_ec_ops = { + .packet = cros_ec_lpc_packet, .command = cros_ec_lpc_command, .check_version = cros_ec_lpc_check_version, }; diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c index 47a9d26c3c7..d741554d8a6 100644 --- a/drivers/misc/cros_ec_sandbox.c +++ b/drivers/misc/cros_ec_sandbox.c @@ -365,7 +365,7 @@ static int process_cmd(struct ec_state *ec, struct fmap_entry *entry; int ret, size; - entry = &ec->ec_config.region[EC_FLASH_REGION_RW]; + entry = &ec->ec_config.region[EC_FLASH_REGION_ACTIVE]; switch (req->cmd) { case EC_VBOOT_HASH_RECALC: @@ -420,7 +420,7 @@ static int process_cmd(struct ec_state *ec, switch (req->region) { case EC_FLASH_REGION_RO: - case EC_FLASH_REGION_RW: + case EC_FLASH_REGION_ACTIVE: case EC_FLASH_REGION_WP_RO: entry = &ec->ec_config.region[req->region]; resp->offset = entry->offset; @@ -491,9 +491,9 @@ int cros_ec_sandbox_packet(struct udevice *udev, int out_bytes, int in_bytes) return in_bytes; } -void cros_ec_check_keyboard(struct cros_ec_dev *dev) +void cros_ec_check_keyboard(struct udevice *dev) { - struct ec_state *ec = dev_get_priv(dev->dev); + struct ec_state *ec = dev_get_priv(dev); ulong start; printf("Press keys for EC to detect on reset (ESC=recovery)..."); diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c index 1b6c0282513..7fef754c634 100644 --- a/drivers/mtd/spi/sandbox.c +++ b/drivers/mtd/spi/sandbox.c @@ -8,6 +8,8 @@ * Licensed under the GPL-2 or later. */ +#define LOG_CATEGORY UCLASS_SPI_FLASH + #include <common.h> #include <dm.h> #include <malloc.h> @@ -41,6 +43,7 @@ enum sandbox_sf_state { SF_WRITE_STATUS, /* write the flash's status register */ }; +#if CONFIG_IS_ENABLED(LOG) static const char *sandbox_sf_state_name(enum sandbox_sf_state state) { static const char * const states[] = { @@ -49,6 +52,7 @@ static const char *sandbox_sf_state_name(enum sandbox_sf_state state) }; return states[state]; } +#endif /* LOG */ /* Bits for the status register */ #define STAT_WIP (1 << 0) @@ -101,69 +105,44 @@ struct sandbox_spi_flash_plat_data { /** * This is a very strange probe function. If it has platform data (which may * have come from the device tree) then this function gets the filename and - * device type from there. Failing that it looks at the command line - * parameter. + * device type from there. */ static int sandbox_sf_probe(struct udevice *dev) { /* spec = idcode:file */ struct sandbox_spi_flash *sbsf = dev_get_priv(dev); - const char *file; size_t len, idname_len; const struct spi_flash_info *data; struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev); struct sandbox_state *state = state_get_current(); + struct dm_spi_slave_platdata *slave_plat; struct udevice *bus = dev->parent; const char *spec = NULL; + struct udevice *emul; int ret = 0; int cs = -1; - int i; debug("%s: bus %d, looking for emul=%p: ", __func__, bus->seq, dev); - if (bus->seq >= 0 && bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS) { - for (i = 0; i < CONFIG_SANDBOX_SPI_MAX_CS; i++) { - if (state->spi[bus->seq][i].emul == dev) - cs = i; - } - } - if (cs == -1) { + ret = sandbox_spi_get_emul(state, bus, dev, &emul); + if (ret) { printf("Error: Unknown chip select for device '%s'\n", - dev->name); - return -EINVAL; + dev->name); + return ret; } + slave_plat = dev_get_parent_platdata(dev); + cs = slave_plat->cs; debug("found at cs %d\n", cs); if (!pdata->filename) { - struct sandbox_state *state = state_get_current(); - - assert(bus->seq != -1); - if (bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS) - spec = state->spi[bus->seq][cs].spec; - if (!spec) { - debug("%s: No spec found for bus %d, cs %d\n", - __func__, bus->seq, cs); - ret = -ENOENT; - goto error; - } - - file = strchr(spec, ':'); - if (!file) { - printf("%s: unable to parse file\n", __func__); - ret = -EINVAL; - goto error; - } - idname_len = file - spec; - pdata->filename = file + 1; - pdata->device_name = spec; - ++file; - } else { - spec = strchr(pdata->device_name, ','); - if (spec) - spec++; - else - spec = pdata->device_name; - idname_len = strlen(spec); + printf("Error: No filename available\n"); + return -EINVAL; } + spec = strchr(pdata->device_name, ','); + if (spec) + spec++; + else + spec = pdata->device_name; + idname_len = strlen(spec); debug("%s: device='%s'\n", __func__, spec); for (data = spi_flash_ids; data->name; data++) { @@ -214,7 +193,7 @@ static void sandbox_sf_cs_activate(struct udevice *dev) { struct sandbox_spi_flash *sbsf = dev_get_priv(dev); - debug("sandbox_sf: CS activated; state is fresh!\n"); + log_content("sandbox_sf: CS activated; state is fresh!\n"); /* CS is asserted, so reset state */ sbsf->off = 0; @@ -226,7 +205,7 @@ static void sandbox_sf_cs_activate(struct udevice *dev) static void sandbox_sf_cs_deactivate(struct udevice *dev) { - debug("sandbox_sf: CS deactivated; cmd done processing!\n"); + log_content("sandbox_sf: CS deactivated; cmd done processing!\n"); } /* @@ -302,8 +281,8 @@ static int sandbox_sf_process_cmd(struct sandbox_spi_flash *sbsf, const u8 *rx, } if (oldstate != sbsf->state) - debug(" cmd: transition to %s state\n", - sandbox_sf_state_name(sbsf->state)); + log_content(" cmd: transition to %s state\n", + sandbox_sf_state_name(sbsf->state)); return 0; } @@ -334,8 +313,8 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, int bytes = bitlen / 8; int ret; - debug("sandbox_sf: state:%x(%s) bytes:%u\n", sbsf->state, - sandbox_sf_state_name(sbsf->state), bytes); + log_content("sandbox_sf: state:%x(%s) bytes:%u\n", sbsf->state, + sandbox_sf_state_name(sbsf->state), bytes); if ((flags & SPI_XFER_BEGIN)) sandbox_sf_cs_activate(dev); @@ -354,7 +333,7 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, case SF_ID: { u8 id; - debug(" id: off:%u tx:", sbsf->off); + log_content(" id: off:%u tx:", sbsf->off); if (sbsf->off < IDCODE_LEN) { /* Extract correct byte from ID 0x00aabbcc */ id = ((JEDEC_MFR(sbsf->data) << 16) | @@ -363,18 +342,18 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, } else { id = 0; } - debug("%d %02x\n", sbsf->off, id); + log_content("%d %02x\n", sbsf->off, id); tx[pos++] = id; ++sbsf->off; break; } case SF_ADDR: - debug(" addr: bytes:%u rx:%02x ", sbsf->addr_bytes, - rx[pos]); + log_content(" addr: bytes:%u rx:%02x ", + sbsf->addr_bytes, rx[pos]); if (sbsf->addr_bytes++ < SF_ADDR_LEN) sbsf->off = (sbsf->off << 8) | rx[pos]; - debug("addr:%06x\n", sbsf->off); + log_content("addr:%06x\n", sbsf->off); if (tx) sandbox_spi_tristate(&tx[pos], 1); @@ -403,8 +382,8 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, sbsf->state = SF_ERASE; goto case_sf_erase; } - debug(" cmd: transition to %s state\n", - sandbox_sf_state_name(sbsf->state)); + log_content(" cmd: transition to %s state\n", + sandbox_sf_state_name(sbsf->state)); break; case SF_READ: /* @@ -413,7 +392,7 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, */ cnt = bytes - pos; - debug(" tx: read(%u)\n", cnt); + log_content(" tx: read(%u)\n", cnt); assert(tx); ret = os_read(sbsf->fd, tx + pos, cnt); if (ret < 0) { @@ -423,19 +402,19 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, pos += ret; break; case SF_READ_STATUS: - debug(" read status: %#x\n", sbsf->status); + log_content(" read status: %#x\n", sbsf->status); cnt = bytes - pos; memset(tx + pos, sbsf->status, cnt); pos += cnt; break; case SF_READ_STATUS1: - debug(" read status: %#x\n", sbsf->status); + log_content(" read status: %#x\n", sbsf->status); cnt = bytes - pos; memset(tx + pos, sbsf->status >> 8, cnt); pos += cnt; break; case SF_WRITE_STATUS: - debug(" write status: %#x (ignored)\n", rx[pos]); + log_content(" write status: %#x (ignored)\n", rx[pos]); pos = bytes; break; case SF_WRITE: @@ -451,7 +430,7 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, } cnt = bytes - pos; - debug(" rx: write(%u)\n", cnt); + log_content(" rx: write(%u)\n", cnt); if (tx) sandbox_spi_tristate(&tx[pos], cnt); ret = os_write(sbsf->fd, rx + pos, cnt); @@ -471,15 +450,15 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, /* verify address is aligned */ if (sbsf->off & (sbsf->erase_size - 1)) { - debug(" sector erase: cmd:%#x needs align:%#x, but we got %#x\n", - sbsf->cmd, sbsf->erase_size, - sbsf->off); + log_content(" sector erase: cmd:%#x needs align:%#x, but we got %#x\n", + sbsf->cmd, sbsf->erase_size, + sbsf->off); sbsf->status &= ~STAT_WEL; goto done; } - debug(" sector erase addr: %u, size: %u\n", sbsf->off, - sbsf->erase_size); + log_content(" sector erase addr: %u, size: %u\n", + sbsf->off, sbsf->erase_size); cnt = bytes - pos; if (tx) @@ -493,13 +472,13 @@ static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen, ret = sandbox_erase_part(sbsf, sbsf->erase_size); sbsf->status &= ~STAT_WEL; if (ret) { - debug("sandbox_sf: Erase failed\n"); + log_content("sandbox_sf: Erase failed\n"); goto done; } goto done; } default: - debug(" ??? no idea what to do ???\n"); + log_content(" ??? no idea what to do ???\n"); goto done; } } @@ -530,31 +509,6 @@ static const struct dm_spi_emul_ops sandbox_sf_emul_ops = { }; #ifdef CONFIG_SPI_FLASH -static int sandbox_cmdline_cb_spi_sf(struct sandbox_state *state, - const char *arg) -{ - unsigned long bus, cs; - const char *spec = sandbox_spi_parse_spec(arg, &bus, &cs); - - if (!spec) - return 1; - - /* - * It is safe to not make a copy of 'spec' because it comes from the - * command line. - * - * TODO(sjg@chromium.org): It would be nice if we could parse the - * spec here, but the problem is that no U-Boot init has been done - * yet. Perhaps we can figure something out. - */ - state->spi[bus][cs].spec = spec; - debug("%s: Setting up spec '%s' for bus %ld, cs %ld\n", __func__, - spec, bus, cs); - - return 0; -} -SANDBOX_CMDLINE_OPT(spi_sf, 1, "connect a SPI flash: <bus>:<cs>:<id>:<file>"); - int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs, struct udevice *bus, ofnode node, const char *spec) { @@ -597,33 +551,6 @@ void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs) state->spi[busnum][cs].emul = NULL; } -static int sandbox_sf_bind_bus_cs(struct sandbox_state *state, int busnum, - int cs, const char *spec) -{ - struct udevice *bus, *slave; - int ret; - - ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, true, &bus); - if (ret) { - printf("Invalid bus %d for spec '%s' (err=%d)\n", busnum, - spec, ret); - return ret; - } - ret = spi_find_chip_select(bus, cs, &slave); - if (!ret) { - printf("Chip select %d already exists for spec '%s'\n", cs, - spec); - return -EEXIST; - } - - ret = device_bind_driver(bus, "spi_flash_std", spec, &slave); - if (ret) - return ret; - - return sandbox_sf_bind_emul(state, busnum, cs, bus, ofnode_null(), - spec); -} - int sandbox_spi_get_emul(struct sandbox_state *state, struct udevice *bus, struct udevice *slave, struct udevice **emulp) @@ -650,35 +577,6 @@ int sandbox_spi_get_emul(struct sandbox_state *state, return 0; } - -int dm_scan_other(bool pre_reloc_only) -{ - struct sandbox_state *state = state_get_current(); - int busnum, cs; - - if (pre_reloc_only) - return 0; - for (busnum = 0; busnum < CONFIG_SANDBOX_SPI_MAX_BUS; busnum++) { - for (cs = 0; cs < CONFIG_SANDBOX_SPI_MAX_CS; cs++) { - const char *spec = state->spi[busnum][cs].spec; - int ret; - - if (spec) { - ret = sandbox_sf_bind_bus_cs(state, busnum, - cs, spec); - if (ret) { - debug("%s: Bind failed for bus %d, cs %d\n", - __func__, busnum, cs); - return ret; - } - debug("%s: Setting up spec '%s' for bus %d, cs %d\n", - __func__, spec, busnum, cs); - } - } - } - - return 0; -} #endif static const struct udevice_id sandbox_sf_ids[] = { diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c index 3858f77a6dd..662525f016f 100644 --- a/drivers/mtd/spi/sf-uclass.c +++ b/drivers/mtd/spi/sf-uclass.c @@ -14,18 +14,18 @@ DECLARE_GLOBAL_DATA_PTR; int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf) { - return sf_get_ops(dev)->read(dev, offset, len, buf); + return log_ret(sf_get_ops(dev)->read(dev, offset, len, buf)); } int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len, const void *buf) { - return sf_get_ops(dev)->write(dev, offset, len, buf); + return log_ret(sf_get_ops(dev)->write(dev, offset, len, buf)); } int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len) { - return sf_get_ops(dev)->erase(dev, offset, len); + return log_ret(sf_get_ops(dev)->erase(dev, offset, len)); } /* diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 42c7cdedf6f..94fde2ae7a3 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -97,7 +97,7 @@ static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len, { struct spi_flash *flash = dev_get_uclass_priv(dev); - return spi_flash_cmd_read_ops(flash, offset, len, buf); + return log_ret(spi_flash_cmd_read_ops(flash, offset, len, buf)); } static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len, diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index c1591242591..92300603644 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -468,17 +468,17 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, size_t len, void *data) { struct spi_slave *spi = flash->spi; - u8 *cmd, cmdsz; + u8 cmdsz; u32 remain_len, read_len, read_addr; int bank_sel = 0; - int ret = -1; + int ret = 0; /* Handle memory-mapped SPI */ if (flash->memory_map) { ret = spi_claim_bus(spi); if (ret) { debug("SF: unable to claim SPI bus\n"); - return ret; + return log_ret(ret); } spi_xfer(spi, 0, NULL, NULL, SPI_XFER_MMAP); spi_flash_copy_mmap(data, flash->memory_map + offset, len); @@ -488,11 +488,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, } cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte; - cmd = calloc(1, cmdsz); - if (!cmd) { - debug("SF: Failed to allocate cmd\n"); - return -ENOMEM; - } + u8 cmd[cmdsz]; cmd[0] = flash->read_cmd; while (len) { @@ -505,7 +501,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, #ifdef CONFIG_SPI_FLASH_BAR ret = write_bar(flash, read_addr); if (ret < 0) - return ret; + return log_ret(ret); bank_sel = flash->bank_curr; #endif remain_len = ((SPI_FLASH_16MB_BOUN << flash->shift) * @@ -535,8 +531,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, ret = clean_bar(flash); #endif - free(cmd); - return ret; + return log_ret(ret); } #ifdef CONFIG_SPI_FLASH_SST diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 29113f79586..eaacd4066e8 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -247,7 +247,7 @@ int dm_pci_run_vga_bios(struct udevice *dev, int (*int15_handler)(void), } if (!board_should_load_oprom(dev)) - return -ENXIO; + return log_msg_ret("Should not load OPROM", -ENXIO); ret = pci_rom_probe(dev, &rom); if (ret) @@ -328,7 +328,7 @@ int vbe_setup_video_priv(struct vesa_mode_info *vesa, struct video_uc_platdata *plat) { if (!vesa->x_resolution) - return -ENXIO; + return log_msg_ret("No x resolution", -ENXIO); uc_priv->xsize = vesa->x_resolution; uc_priv->ysize = vesa->y_resolution; switch (vesa->bits_per_pixel) { diff --git a/drivers/pwm/sandbox_pwm.c b/drivers/pwm/sandbox_pwm.c index 4b50b19c618..28988187e03 100644 --- a/drivers/pwm/sandbox_pwm.c +++ b/drivers/pwm/sandbox_pwm.c @@ -14,6 +14,14 @@ enum { NUM_CHANNELS = 3, }; +/** + * struct sandbox_pwm_chan - a sandbox PWM channel + * + * @period_ns: Period of the PWM in nanoseconds + * @duty_ns: Current duty cycle of the PWM in nanoseconds + * @enable: true if the PWM is enabled + * @polarity: true if the PWM polarity is active high + */ struct sandbox_pwm_chan { uint period_ns; uint duty_ns; @@ -25,6 +33,23 @@ struct sandbox_pwm_priv { struct sandbox_pwm_chan chan[NUM_CHANNELS]; }; +int sandbox_pwm_get_config(struct udevice *dev, uint channel, uint *period_nsp, + uint *duty_nsp, bool *enablep, bool *polarityp) +{ + struct sandbox_pwm_priv *priv = dev_get_priv(dev); + struct sandbox_pwm_chan *chan; + + if (channel >= NUM_CHANNELS) + return -ENOSPC; + chan = &priv->chan[channel]; + *period_nsp = chan->period_ns; + *duty_nsp = chan->duty_ns; + *enablep = chan->enable; + *polarityp = chan->polarity; + + return 0; +} + static int sandbox_pwm_set_config(struct udevice *dev, uint channel, uint period_ns, uint duty_ns) { diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 54365092ec4..bcc01b135e5 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -13,6 +13,24 @@ config DM_RTC drivers to perform the actual functions. See rtc.h for a description of the API. +config SPL_DM_RTC + bool "Enable Driver Model for RTC drivers in SPL" + depends on SPL_DM + help + Enable drver model for real-time-clock drivers. The RTC uclass + then provides the rtc_get()/rtc_set() interface, delegating to + drivers to perform the actual functions. See rtc.h for a + description of the API. + +config TPL_DM_RTC + bool "Enable Driver Model for RTC drivers in TPL" + depends on TPL_DM + help + Enable drver model for real-time-clock drivers. The RTC uclass + then provides the rtc_get()/rtc_set() interface, delegating to + drivers to perform the actual functions. See rtc.h for a + description of the API. + config RTC_PCF2127 bool "Enable PCF2127 driver" depends on DM_RTC @@ -68,4 +86,12 @@ config RTC_S35392A help Enable s35392a driver which provides rtc get and set function. +config RTC_MC146818 + bool "Enable MC146818 driver" + help + This is a widely used real-time clock chip originally by Motorola + and now available from NXP. It includes a battery-backed real-time + clock with a wide array of features and 50 bytes of general-purpose, + battery-backed RAM. The driver supports access to the clock and RAM. + endmenu diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 513e3ffc079..1724602f1cb 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -4,7 +4,7 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. #ccflags-y += -DDEBUG -obj-$(CONFIG_DM_RTC) += rtc-uclass.o +obj-$(CONFIG_$(SPL_TPL_)DM_RTC) += rtc-uclass.o obj-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o obj-y += date.o diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 5fa27254e30..597db4b9cbb 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -53,6 +53,16 @@ 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 TPL_SERIAL_PRESENT + bool "Provide a serial driver in TPL" + depends on DM_SERIAL + default y + help + In very space-constrained devices even the full UART driver is too + large. In this case the debug UART can still be used in some cases. + This option enables the full UART in TPL, so if is it disabled, + the full UART driver will be omitted, thus saving space. + # Logic to allow us to use the imply keyword to set what the default port # should be. The default is otherwise 1. config CONS_INDEX_0 @@ -324,6 +334,15 @@ config DEBUG_UART_MXC will need to provide parameters to make this work. The driver will be available until the real driver model serial is running. +config DEBUG_UART_SANDBOX + bool "sandbox" + depends on SANDBOX_SERIAL + help + Select this to enable the debug UART using the sandbox driver. This + provides basic serial output from the console without needing to + start up driver model. The driver will be available until the real + driver model serial is running. + config DEBUG_UART_STM32 bool "STMicroelectronics STM32" depends on STM32_SERIAL @@ -354,6 +373,7 @@ endchoice config DEBUG_UART_BASE hex "Base address of UART" depends on DEBUG_UART + default 0 if DEBUG_UART_SANDBOX help This is the base address of your UART for memory-mapped UARTs. @@ -363,6 +383,7 @@ config DEBUG_UART_BASE config DEBUG_UART_CLOCK int "UART input clock" depends on DEBUG_UART + default 0 if DEBUG_UART_SANDBOX help The UART input clock determines the speed of the internal UART circuitry. The baud rate is derived from this by dividing the input diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c index 94b4fdfb171..4a05ea44ce9 100644 --- a/drivers/serial/sandbox.c +++ b/drivers/serial/sandbox.c @@ -22,6 +22,8 @@ DECLARE_GLOBAL_DATA_PTR; +#if CONFIG_IS_ENABLED(OF_CONTROL) + /* * * serial_buf: A buffer that holds keyboard characters for the @@ -124,7 +126,7 @@ static int sandbox_serial_pending(struct udevice *dev, bool input) if (next_index == serial_buf_read) return 1; /* buffer full */ - count = os_read_no_block(0, &serial_buf[serial_buf_write], 1); + count = os_read(0, &serial_buf[serial_buf_write], 1); if (count == 1) serial_buf_write = next_index; @@ -142,6 +144,24 @@ static int sandbox_serial_getc(struct udevice *dev) serial_buf_read = increment_buffer_index(serial_buf_read); return result; } +#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ + +#ifdef CONFIG_DEBUG_UART_SANDBOX + +#include <debug_uart.h> + +static inline void _debug_uart_init(void) +{ +} + +static inline void _debug_uart_putc(int ch) +{ + os_putc(ch); +} + +DEBUG_UART_FUNCS + +#endif /* CONFIG_DEBUG_UART_SANDBOX */ static int sandbox_serial_setconfig(struct udevice *dev, uint serial_config) { @@ -156,6 +176,7 @@ static int sandbox_serial_setconfig(struct udevice *dev, uint serial_config) return 0; } +#if CONFIG_IS_ENABLED(OF_CONTROL) static const char * const ansi_colour[] = { "black", "red", "green", "yellow", "blue", "megenta", "cyan", "white", @@ -215,3 +236,4 @@ U_BOOT_DEVICE(serial_sandbox_non_fdt) = { .name = "serial_sandbox", .platdata = &platdata_non_fdt, }; +#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index ffdcae09318..e50f0aa8510 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -26,6 +26,7 @@ static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; #error "Serial is required before relocation - define CONFIG_$(SPL_)SYS_MALLOC_F_LEN to make this work" #endif +#if CONFIG_IS_ENABLED(SERIAL_PRESENT) static int serial_check_stdout(const void *blob, struct udevice **devp) { int node; @@ -150,12 +151,15 @@ static void serial_find_console_or_panic(void) panic_str("No serial driver found"); #endif } +#endif /* CONFIG_SERIAL_PRESENT */ /* Called prior to relocation */ int serial_init(void) { +#if CONFIG_IS_ENABLED(SERIAL_PRESENT) serial_find_console_or_panic(); gd->flags |= GD_FLG_SERIAL_READY; +#endif return 0; } diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c index 75ba6a1ed7e..906401ec8ab 100644 --- a/drivers/spi/sandbox_spi.c +++ b/drivers/spi/sandbox_spi.c @@ -8,6 +8,8 @@ * Licensed under the GPL-2 or later. */ +#define LOG_CATEGORY UCLASS_SPI + #include <common.h> #include <dm.h> #include <malloc.h> @@ -56,7 +58,6 @@ static int sandbox_spi_xfer(struct udevice *slave, unsigned int bitlen, struct udevice *emul; uint bytes = bitlen / 8, i; int ret; - u8 *tx = (void *)dout, *rx = din; uint busnum, cs; if (bitlen == 0) @@ -87,37 +88,16 @@ static int sandbox_spi_xfer(struct udevice *slave, unsigned int bitlen, if (ret) return ret; - /* make sure rx/tx buffers are full so clients can assume */ - if (!tx) { - debug("sandbox_spi: xfer: auto-allocating tx scratch buffer\n"); - tx = malloc(bytes); - if (!tx) { - debug("sandbox_spi: Out of memory\n"); - return -ENOMEM; - } - } - if (!rx) { - debug("sandbox_spi: xfer: auto-allocating rx scratch buffer\n"); - rx = malloc(bytes); - if (!rx) { - debug("sandbox_spi: Out of memory\n"); - return -ENOMEM; - } - } - ops = spi_emul_get_ops(emul); ret = ops->xfer(emul, bitlen, dout, din, flags); - debug("sandbox_spi: xfer: got back %i (that's %s)\n rx:", - ret, ret ? "bad" : "good"); - for (i = 0; i < bytes; ++i) - debug(" %u:%02x", i, rx[i]); - debug("\n"); - - if (tx != dout) - free(tx); - if (rx != din) - free(rx); + log_content("sandbox_spi: xfer: got back %i (that's %s)\n rx:", + ret, ret ? "bad" : "good"); + if (din) { + for (i = 0; i < bytes; ++i) + log_content(" %u:%02x", i, ((u8 *)din)[i]); + } + log_content("\n"); return ret; } diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index c517d066f69..b84255bd274 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -63,11 +63,11 @@ int dm_spi_claim_bus(struct udevice *dev) int ret = spi_set_speed_mode(bus, speed, slave->mode); if (ret) - return ret; + return log_ret(ret); slave->speed = speed; } - return ops->claim_bus ? ops->claim_bus(dev) : 0; + return log_ret(ops->claim_bus ? ops->claim_bus(dev) : 0); } void dm_spi_release_bus(struct udevice *dev) @@ -92,7 +92,7 @@ int dm_spi_xfer(struct udevice *dev, unsigned int bitlen, int spi_claim_bus(struct spi_slave *slave) { - return dm_spi_claim_bus(slave->dev); + return log_ret(dm_spi_claim_bus(slave->dev)); } void spi_release_bus(struct spi_slave *slave) diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c index 06ef0ed96c7..ad831c703a9 100644 --- a/drivers/sysreset/sysreset-uclass.c +++ b/drivers/sysreset/sysreset-uclass.c @@ -4,6 +4,8 @@ * Written by Simon Glass <sjg@chromium.org> */ +#define LOG_CATEGORY UCLASS_SYSRESET + #include <common.h> #include <sysreset.h> #include <dm.h> @@ -34,6 +36,16 @@ int sysreset_get_status(struct udevice *dev, char *buf, int size) return ops->get_status(dev, buf, size); } +int sysreset_get_last(struct udevice *dev) +{ + struct sysreset_ops *ops = sysreset_get_ops(dev); + + if (!ops->get_last) + return -ENOSYS; + + return ops->get_last(dev); +} + int sysreset_walk(enum sysreset_t type) { struct udevice *dev; @@ -53,6 +65,26 @@ int sysreset_walk(enum sysreset_t type) return ret; } +int sysreset_get_last_walk(void) +{ + struct udevice *dev; + int value = -ENOENT; + + for (uclass_first_device(UCLASS_SYSRESET, &dev); + dev; + uclass_next_device(&dev)) { + int ret; + + ret = sysreset_get_last(dev); + if (ret >= 0) { + value = ret; + break; + } + } + + return value; +} + void sysreset_walk_halt(enum sysreset_t type) { int ret; @@ -64,7 +96,7 @@ void sysreset_walk_halt(enum sysreset_t type) mdelay(100); /* Still no reset? Give up */ - debug("System reset not supported on this platform\n"); + log_err("System reset not supported on this platform\n"); hang(); } diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c index 75004d9f774..7f6d4186e16 100644 --- a/drivers/sysreset/sysreset_sandbox.c +++ b/drivers/sysreset/sysreset_sandbox.c @@ -36,6 +36,11 @@ int sandbox_warm_sysreset_get_status(struct udevice *dev, char *buf, int size) return 0; } +int sandbox_warm_sysreset_get_last(struct udevice *dev) +{ + return SYSRESET_WARM; +} + static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type) { struct sandbox_state *state = state_get_current(); @@ -58,6 +63,9 @@ static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type) return -EACCES; sandbox_exit(); break; + case SYSRESET_POWER_OFF: + if (!state->sysreset_allowed[type]) + return -EACCES; default: return -ENOSYS; } @@ -74,9 +82,15 @@ int sandbox_sysreset_get_status(struct udevice *dev, char *buf, int size) return 0; } +int sandbox_sysreset_get_last(struct udevice *dev) +{ + return SYSRESET_COLD; +} + static struct sysreset_ops sandbox_sysreset_ops = { .request = sandbox_sysreset_request, .get_status = sandbox_sysreset_get_status, + .get_last = sandbox_sysreset_get_last, }; static const struct udevice_id sandbox_sysreset_ids[] = { @@ -94,6 +108,7 @@ U_BOOT_DRIVER(sysreset_sandbox) = { static struct sysreset_ops sandbox_warm_sysreset_ops = { .request = sandbox_warm_sysreset_request, .get_status = sandbox_warm_sysreset_get_status, + .get_last = sandbox_warm_sysreset_get_last, }; static const struct udevice_id sandbox_warm_sysreset_ids[] = { diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile index af473ef662e..94c337b8ed3 100644 --- a/drivers/tpm/Makefile +++ b/drivers/tpm/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. -obj-$(CONFIG_TPM) += tpm-uclass.o +obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm-uclass.o obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o obj-$(CONFIG_TPM_TIS_INFINEON) += tpm_tis_infineon.o diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c index c83f53ab86b..1b11c93194d 100644 --- a/drivers/tpm/tpm-uclass.c +++ b/drivers/tpm/tpm-uclass.c @@ -126,8 +126,11 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size, } UCLASS_DRIVER(tpm) = { - .id = UCLASS_TPM, - .name = "tpm", - .flags = DM_UC_FLAG_SEQ_ALIAS, + .id = UCLASS_TPM, + .name = "tpm", + .flags = DM_UC_FLAG_SEQ_ALIAS, +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) + .post_bind = dm_scan_fdt_dev, +#endif .per_device_auto_alloc_size = sizeof(struct tpm_chip_priv), }; diff --git a/drivers/tpm/tpm_tis_lpc.c b/drivers/tpm/tpm_tis_lpc.c index 7664bb1a605..e993fd9f833 100644 --- a/drivers/tpm/tpm_tis_lpc.c +++ b/drivers/tpm/tpm_tis_lpc.c @@ -164,7 +164,7 @@ static int tpm_tis_lpc_probe(struct udevice *dev) u32 didvid; ulong chip_type = dev_get_driver_data(dev); - addr = devfdt_get_addr(dev); + addr = dev_read_addr(dev); if (addr == FDT_ADDR_T_NONE) return -EINVAL; priv->regs = map_sysmem(addr, 0); diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c index 8816d55759f..79517f015af 100644 --- a/drivers/tpm/tpm_tis_sandbox.c +++ b/drivers/tpm/tpm_tis_sandbox.c @@ -13,6 +13,10 @@ /* TPM NVRAM location indices. */ #define FIRMWARE_NV_INDEX 0x1007 #define KERNEL_NV_INDEX 0x1008 +#define BACKUP_NV_INDEX 0x1009 +#define FWMP_NV_INDEX 0x100a +#define REC_HASH_NV_INDEX 0x100b +#define REC_HASH_NV_SIZE VB2_SHA256_DIGEST_SIZE #define NV_DATA_PUBLIC_PERMISSIONS_OFFSET 60 @@ -45,18 +49,28 @@ enum { NV_GLOBAL_LOCK, NV_SEQ_FIRMWARE, NV_SEQ_KERNEL, + NV_SEQ_BACKUP, + NV_SEQ_FWMP, + NV_SEQ_REC_HASH, + NV_SEQ_COUNT, }; /* Size of each non-volatile space */ #define NV_DATA_SIZE 0x20 +struct nvdata_state { + bool present; + u8 data[NV_DATA_SIZE]; +}; + /* * Information about our TPM emulation. This is preserved in the sandbox * state file if enabled. */ static struct tpm_state { - uint8_t nvdata[NV_SEQ_COUNT][NV_DATA_SIZE]; + bool valid; + struct nvdata_state nvdata[NV_SEQ_COUNT]; } g_state; /** @@ -82,9 +96,12 @@ static int sandbox_tpm_read_state(const void *blob, int node) sprintf(prop_name, "nvdata%d", i); prop = fdt_getprop(blob, node, prop_name, &len); - if (prop && len == NV_DATA_SIZE) - memcpy(g_state.nvdata[i], prop, NV_DATA_SIZE); + if (prop && len == NV_DATA_SIZE) { + memcpy(g_state.nvdata[i].data, prop, NV_DATA_SIZE); + g_state.nvdata[i].present = true; + } } + g_state.valid = true; return 0; } @@ -110,9 +127,11 @@ static int sandbox_tpm_write_state(void *blob, int node) for (i = 0; i < NV_SEQ_COUNT; i++) { char prop_name[20]; - sprintf(prop_name, "nvdata%d", i); - fdt_setprop(blob, node, prop_name, g_state.nvdata[i], - NV_DATA_SIZE); + if (g_state.nvdata[i].present) { + sprintf(prop_name, "nvdata%d", i); + fdt_setprop(blob, node, prop_name, + g_state.nvdata[i].data, NV_DATA_SIZE); + } } return 0; @@ -128,6 +147,12 @@ static int index_to_seq(uint32_t index) return NV_SEQ_FIRMWARE; case KERNEL_NV_INDEX: return NV_SEQ_KERNEL; + case BACKUP_NV_INDEX: + return NV_SEQ_BACKUP; + case FWMP_NV_INDEX: + return NV_SEQ_FWMP; + case REC_HASH_NV_INDEX: + return NV_SEQ_REC_HASH; case 0: return NV_GLOBAL_LOCK; } @@ -136,6 +161,21 @@ static int index_to_seq(uint32_t index) return -1; } +static void handle_cap_flag_space(u8 **datap, uint index) +{ + struct tpm_nv_data_public pub; + + /* TPM_NV_PER_PPWRITE */ + memset(&pub, '\0', sizeof(pub)); + pub.nv_index = __cpu_to_be32(index); + pub.pcr_info_read.pcr_selection.size_of_select = __cpu_to_be16( + sizeof(pub.pcr_info_read.pcr_selection.pcr_select)); + pub.permission.attributes = __cpu_to_be32(1); + pub.pcr_info_write = pub.pcr_info_read; + memcpy(*datap, &pub, sizeof(pub)); + *datap += sizeof(pub); +} + static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size, uint8_t *recvbuf, size_t *recv_len) @@ -151,29 +191,45 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, *recv_len, code); print_buffer(0, sendbuf, 1, send_size, 0); switch (code) { - case 0x65: /* get flags */ + case TPM_CMD_GET_CAPABILITY: type = get_unaligned_be32(sendbuf + 14); switch (type) { - case 4: + case TPM_CAP_FLAG: index = get_unaligned_be32(sendbuf + 18); printf("Get flags index %#02x\n", index); *recv_len = 22; memset(recvbuf, '\0', *recv_len); - put_unaligned_be32(22, recvbuf + - TPM_RESPONSE_HEADER_LENGTH); data = recvbuf + TPM_RESPONSE_HEADER_LENGTH + sizeof(uint32_t); switch (index) { case FIRMWARE_NV_INDEX: break; case KERNEL_NV_INDEX: - /* TPM_NV_PER_PPWRITE */ - put_unaligned_be32(1, data + - NV_DATA_PUBLIC_PERMISSIONS_OFFSET); + handle_cap_flag_space(&data, index); + *recv_len = data - recvbuf - + TPM_RESPONSE_HEADER_LENGTH - + sizeof(uint32_t); + break; + case TPM_CAP_FLAG_PERMANENT: { + struct tpm_permanent_flags *pflags; + + pflags = (struct tpm_permanent_flags *)data; + memset(pflags, '\0', sizeof(*pflags)); + put_unaligned_be32(TPM_TAG_PERMANENT_FLAGS, + &pflags->tag); + *recv_len = TPM_HEADER_SIZE + 4 + + sizeof(*pflags); break; } + default: + printf(" ** Unknown flags index %x\n", index); + return -ENOSYS; + } + put_unaligned_be32(*recv_len, + recvbuf + + TPM_RESPONSE_HEADER_LENGTH); break; - case 0x11: /* TPM_CAP_NV_INDEX */ + case TPM_CAP_NV_INDEX: index = get_unaligned_be32(sendbuf + 18); printf("Get cap nv index %#02x\n", index); put_unaligned_be32(22, recvbuf + @@ -182,27 +238,29 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, default: printf(" ** Unknown 0x65 command type %#02x\n", type); - return -1; + return -ENOSYS; } break; - case 0xcd: /* nvwrite */ + case TPM_CMD_NV_WRITE_VALUE: index = get_unaligned_be32(sendbuf + 10); length = get_unaligned_be32(sendbuf + 18); seq = index_to_seq(index); if (seq < 0) - return -1; + return -EINVAL; printf("tpm: nvwrite index=%#02x, len=%#02x\n", index, length); - memcpy(&tpm->nvdata[seq], sendbuf + 22, length); + memcpy(&tpm->nvdata[seq].data, sendbuf + 22, length); + tpm->nvdata[seq].present = true; *recv_len = 12; memset(recvbuf, '\0', *recv_len); break; - case 0xcf: /* nvread */ + case TPM_CMD_NV_READ_VALUE: /* nvread */ index = get_unaligned_be32(sendbuf + 10); length = get_unaligned_be32(sendbuf + 18); seq = index_to_seq(index); if (seq < 0) - return -1; - printf("tpm: nvread index=%#02x, len=%#02x\n", index, length); + return -EINVAL; + printf("tpm: nvread index=%#02x, len=%#02x, seq=%#02x\n", index, + length, seq); *recv_len = TPM_RESPONSE_HEADER_LENGTH + sizeof(uint32_t) + length; memset(recvbuf, '\0', *recv_len); @@ -220,24 +278,33 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, offsetof(struct rollback_space_kernel, crc8)); memcpy(data, &rsk, sizeof(rsk)); + } else if (!tpm->nvdata[seq].present) { + put_unaligned_be32(TPM_BADINDEX, recvbuf + + sizeof(uint16_t) + sizeof(uint32_t)); } else { memcpy(recvbuf + TPM_RESPONSE_HEADER_LENGTH + - sizeof(uint32_t), &tpm->nvdata[seq], length); + sizeof(uint32_t), &tpm->nvdata[seq].data, + length); } break; - case 0x14: /* tpm extend */ + case TPM_CMD_EXTEND: + *recv_len = 30; + memset(recvbuf, '\0', *recv_len); + break; + case TPM_CMD_NV_DEFINE_SPACE: case 0x15: /* pcr read */ case 0x5d: /* force clear */ case 0x6f: /* physical enable */ case 0x72: /* physical set deactivated */ case 0x99: /* startup */ + case 0x50: /* self test full */ case 0x4000000a: /* assert physical presence */ *recv_len = 12; memset(recvbuf, '\0', *recv_len); break; default: printf("Unknown tpm command %02x\n", code); - return -1; + return -ENOSYS; } return 0; diff --git a/drivers/video/backlight-uclass.c b/drivers/video/backlight-uclass.c index 92715e2f130..0aadf8a1f97 100644 --- a/drivers/video/backlight-uclass.c +++ b/drivers/video/backlight-uclass.c @@ -18,6 +18,16 @@ int backlight_enable(struct udevice *dev) return ops->enable(dev); } +int backlight_set_brightness(struct udevice *dev, int percent) +{ + const struct backlight_ops *ops = backlight_get_ops(dev); + + if (!ops->set_brightness) + return -ENOSYS; + + return ops->set_brightness(dev, percent); +} + UCLASS_DRIVER(backlight) = { .id = UCLASS_PANEL_BACKLIGHT, .name = "backlight", diff --git a/drivers/video/panel-uclass.c b/drivers/video/panel-uclass.c index aec44a8bf7a..246d1b2836d 100644 --- a/drivers/video/panel-uclass.c +++ b/drivers/video/panel-uclass.c @@ -18,6 +18,24 @@ int panel_enable_backlight(struct udevice *dev) return ops->enable_backlight(dev); } +/** + * panel_set_backlight - Set brightness for the panel backlight + * + * @dev: Panel device containing the backlight to update + * @percent: Brightness value (0=off, 1=min brightness, + * 100=full brightness) + * @return 0 if OK, -ve on error + */ +int panel_set_backlight(struct udevice *dev, int percent) +{ + struct panel_ops *ops = panel_get_ops(dev); + + if (!ops->set_backlight) + return -ENOSYS; + + return ops->set_backlight(dev, percent); +} + int panel_get_display_timing(struct udevice *dev, struct display_timing *timings) { diff --git a/drivers/video/pwm_backlight.c b/drivers/video/pwm_backlight.c index 53953179bfb..c13a9077090 100644 --- a/drivers/video/pwm_backlight.c +++ b/drivers/video/pwm_backlight.c @@ -4,6 +4,8 @@ * Written by Simon Glass <sjg@chromium.org> */ +#define LOG_CATEGORY UCLASS_PANEL_BACKLIGHT + #include <common.h> #include <dm.h> #include <backlight.h> @@ -11,48 +13,156 @@ #include <asm/gpio.h> #include <power/regulator.h> +/** + * Private information for the PWM backlight + * + * If @num_levels is 0 then the levels are simple values with the backlight + * value going between the minimum (default 0) and the maximum (default 255). + * Otherwise the levels are an index into @levels (0..n-1). + * + * @reg: Regulator to enable to turn the backlight on (NULL if none) + * @enable, GPIO to set to enable the backlight (can be missing) + * @pwm: PWM to use to change the backlight brightness + * @channel: PWM channel to use + * @period_ns: Period of the backlight in nanoseconds + * @levels: Levels for the backlight, or NULL if not using indexed levels + * @num_levels: Number of levels + * @cur_level: Current level for the backlight (index or value) + * @default_level: Default level for the backlight (index or value) + * @min_level: Minimum level of the backlight (full off) + * @min_level: Maximum level of the backlight (full on) + * @enabled: true if backlight is enabled + */ struct pwm_backlight_priv { struct udevice *reg; struct gpio_desc enable; struct udevice *pwm; uint channel; uint period_ns; + u32 *levels; + int num_levels; uint default_level; + int cur_level; uint min_level; uint max_level; + bool enabled; }; -static int pwm_backlight_enable(struct udevice *dev) +static int set_pwm(struct pwm_backlight_priv *priv) { - struct pwm_backlight_priv *priv = dev_get_priv(dev); - struct dm_regulator_uclass_platdata *plat; uint duty_cycle; int ret; - if (priv->reg) { - plat = dev_get_uclass_platdata(priv->reg); - debug("%s: Enable '%s', regulator '%s'/'%s'\n", __func__, - dev->name, priv->reg->name, plat->name); - ret = regulator_set_enable(priv->reg, true); - if (ret) { - debug("%s: Cannot enable regulator for PWM '%s'\n", - __func__, dev->name); - return ret; - } - mdelay(120); - } - - duty_cycle = priv->period_ns * (priv->default_level - priv->min_level) / + duty_cycle = priv->period_ns * (priv->cur_level - priv->min_level) / (priv->max_level - priv->min_level + 1); ret = pwm_set_config(priv->pwm, priv->channel, priv->period_ns, duty_cycle); + + return log_ret(ret); +} + +static int enable_sequence(struct udevice *dev, int seq) +{ + struct pwm_backlight_priv *priv = dev_get_priv(dev); + int ret; + + switch (seq) { + case 0: + if (priv->reg) { + __maybe_unused struct dm_regulator_uclass_platdata + *plat; + + plat = dev_get_uclass_platdata(priv->reg); + log_debug("Enable '%s', regulator '%s'/'%s'\n", + dev->name, priv->reg->name, plat->name); + ret = regulator_set_enable(priv->reg, true); + if (ret) { + log_debug("Cannot enable regulator for PWM '%s'\n", + __func__, dev->name); + return log_ret(ret); + } + mdelay(120); + } + break; + case 1: + mdelay(10); + dm_gpio_set_value(&priv->enable, 1); + break; + } + + return 0; +} + +static int pwm_backlight_enable(struct udevice *dev) +{ + struct pwm_backlight_priv *priv = dev_get_priv(dev); + int ret; + + ret = enable_sequence(dev, 0); + if (ret) + return log_ret(ret); + ret = set_pwm(priv); if (ret) - return ret; + return log_ret(ret); ret = pwm_set_enable(priv->pwm, priv->channel, true); if (ret) - return ret; - mdelay(10); - dm_gpio_set_value(&priv->enable, 1); + return log_ret(ret); + ret = enable_sequence(dev, 1); + if (ret) + return log_ret(ret); + priv->enabled = true; + + return 0; +} + +static int pwm_backlight_set_brightness(struct udevice *dev, int percent) +{ + struct pwm_backlight_priv *priv = dev_get_priv(dev); + bool disable = false; + int level; + int ret; + + if (!priv->enabled) { + ret = enable_sequence(dev, 0); + if (ret) + return log_ret(ret); + } + if (percent == BACKLIGHT_OFF) { + disable = true; + percent = 0; + } + if (percent == BACKLIGHT_DEFAULT) { + level = priv->default_level; + } else { + if (priv->levels) { + level = priv->levels[percent * (priv->num_levels - 1) + / 100]; + } else { + level = priv->min_level + + (priv->max_level - priv->min_level) * + percent / 100; + } + } + priv->cur_level = level; + + ret = set_pwm(priv); + if (ret) + return log_ret(ret); + if (!priv->enabled) { + ret = enable_sequence(dev, 1); + if (ret) + return log_ret(ret); + priv->enabled = true; + } + if (disable) { + dm_gpio_set_value(&priv->enable, 0); + if (priv->reg) { + ret = regulator_set_enable(priv->reg, false); + if (ret) + return log_ret(ret); + } + priv->enabled = false; + } return 0; } @@ -64,31 +174,32 @@ static int pwm_backlight_ofdata_to_platdata(struct udevice *dev) int index, ret, count, len; const u32 *cell; - debug("%s: start\n", __func__); + log_debug("start\n"); ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, "power-supply", &priv->reg); if (ret) - debug("%s: Cannot get power supply: ret=%d\n", __func__, ret); + log_debug("Cannot get power supply: ret=%d\n", ret); ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, GPIOD_IS_OUT); if (ret) { - debug("%s: Warning: cannot get enable GPIO: ret=%d\n", - __func__, ret); + log_debug("Warning: cannot get enable GPIO: ret=%d\n", ret); if (ret != -ENOENT) - return ret; + return log_ret(ret); } ret = dev_read_phandle_with_args(dev, "pwms", "#pwm-cells", 0, 0, &args); if (ret) { - debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret); - return ret; + log_debug("Cannot get PWM phandle: ret=%d\n", ret); + return log_ret(ret); } ret = uclass_get_device_by_ofnode(UCLASS_PWM, args.node, &priv->pwm); if (ret) { - debug("%s: Cannot get PWM: ret=%d\n", __func__, ret); - return ret; + log_debug("Cannot get PWM: ret=%d\n", ret); + return log_ret(ret); } + if (args.args_count < 2) + return log_msg_ret("Not enough arguments to pwm\n", -EINVAL); priv->channel = args.args[0]; priv->period_ns = args.args[1]; @@ -96,13 +207,20 @@ static int pwm_backlight_ofdata_to_platdata(struct udevice *dev) cell = dev_read_prop(dev, "brightness-levels", &len); count = len / sizeof(u32); if (cell && count > index) { - priv->default_level = fdt32_to_cpu(cell[index]); - priv->max_level = fdt32_to_cpu(cell[count - 1]); + priv->levels = malloc(len); + if (!priv->levels) + return log_ret(-ENOMEM); + dev_read_u32_array(dev, "brightness-levels", priv->levels, + count); + priv->num_levels = count; + priv->default_level = priv->levels[index]; + priv->max_level = priv->levels[count - 1]; } else { priv->default_level = index; priv->max_level = 255; } - debug("%s: done\n", __func__); + priv->cur_level = priv->default_level; + log_debug("done\n"); return 0; @@ -114,7 +232,8 @@ static int pwm_backlight_probe(struct udevice *dev) } static const struct backlight_ops pwm_backlight_ops = { - .enable = pwm_backlight_enable, + .enable = pwm_backlight_enable, + .set_brightness = pwm_backlight_set_brightness, }; static const struct udevice_id pwm_backlight_ids[] = { diff --git a/drivers/video/simple_panel.c b/drivers/video/simple_panel.c index 6c604f9bedb..7a968e740c5 100644 --- a/drivers/video/simple_panel.c +++ b/drivers/video/simple_panel.c @@ -32,6 +32,21 @@ static int simple_panel_enable_backlight(struct udevice *dev) return 0; } +static int simple_panel_set_backlight(struct udevice *dev, int percent) +{ + struct simple_panel_priv *priv = dev_get_priv(dev); + int ret; + + debug("%s: start, backlight = '%s'\n", __func__, priv->backlight->name); + dm_gpio_set_value(&priv->enable, 1); + ret = backlight_set_brightness(priv->backlight, percent); + debug("%s: done, ret = %d\n", __func__, ret); + if (ret) + return ret; + + return 0; +} + static int simple_panel_ofdata_to_platdata(struct udevice *dev) { struct simple_panel_priv *priv = dev_get_priv(dev); @@ -51,7 +66,7 @@ static int simple_panel_ofdata_to_platdata(struct udevice *dev) "backlight", &priv->backlight); if (ret) { debug("%s: Cannot get backlight: ret=%d\n", __func__, ret); - return ret; + return log_ret(ret); } ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, GPIOD_IS_OUT); @@ -59,7 +74,7 @@ static int simple_panel_ofdata_to_platdata(struct udevice *dev) debug("%s: Warning: cannot get enable GPIO: ret=%d\n", __func__, ret); if (ret != -ENOENT) - return ret; + return log_ret(ret); } return 0; @@ -82,6 +97,7 @@ static int simple_panel_probe(struct udevice *dev) static const struct panel_ops simple_panel_ops = { .enable_backlight = simple_panel_enable_backlight, + .set_backlight = simple_panel_set_backlight, }; static const struct udevice_id simple_panel_ids[] = { diff --git a/drivers/video/tegra124/sor.c b/drivers/video/tegra124/sor.c index 91e61b58527..172bb14d6c8 100644 --- a/drivers/video/tegra124/sor.c +++ b/drivers/video/tegra124/sor.c @@ -533,7 +533,8 @@ static int tegra_dc_sor_power_up(struct udevice *dev, int is_lvds) #if DEBUG_SOR static void dump_sor_reg(struct tegra_dc_sor_data *sor) { -#define DUMP_REG(a) printk(BIOS_INFO, "%-32s %03x %08x\n", \ +#define DUMP_REG(a) printk(BIOS_INFO, \ + "%-32s %03x %08x\n", \ #a, a, tegra_sor_readl(sor, a)); DUMP_REG(SUPER_STATE0); diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 7f95e9c6e56..1874887f2f3 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -86,7 +86,7 @@ static int vidconsole_back(struct udevice *dev) if (priv->ycur < 0) priv->ycur = 0; } - video_sync(dev->parent); + video_sync(dev->parent, false); return 0; } @@ -113,7 +113,7 @@ static void vidconsole_newline(struct udevice *dev) } priv->last_ch = 0; - video_sync(dev->parent); + video_sync(dev->parent, false); } static const struct vid_rgb colors[VID_COLOR_COUNT] = { @@ -293,7 +293,7 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) if (mode == 2) { video_clear(dev->parent); - video_sync(dev->parent); + video_sync(dev->parent, false); priv->ycur = 0; priv->xcur_frac = priv->xstart_frac; } else { @@ -449,7 +449,7 @@ static void vidconsole_putc(struct stdio_dev *sdev, const char ch) struct udevice *dev = sdev->priv; vidconsole_put_char(dev, ch); - video_sync(dev->parent); + video_sync(dev->parent, false); } static void vidconsole_puts(struct stdio_dev *sdev, const char *s) @@ -458,7 +458,7 @@ static void vidconsole_puts(struct stdio_dev *sdev, const char *s) while (*s) vidconsole_put_char(dev, *s++); - video_sync(dev->parent); + video_sync(dev->parent, false); } /* Set up the number of rows and colours (rotated drivers override this) */ @@ -511,6 +511,8 @@ void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row) struct udevice *vid_dev = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); + col *= priv->x_charsize; + row *= priv->y_charsize; priv->xcur_frac = VID_TO_POS(min_t(short, col, vid_priv->xsize - 1)); priv->ycur = min_t(short, row, vid_priv->ysize - 1); } @@ -547,7 +549,7 @@ static int do_video_puts(cmd_tbl_t *cmdtp, int flag, int argc, for (s = argv[1]; *s; s++) vidconsole_put_char(dev, *s); - video_sync(dev->parent); + video_sync(dev->parent, false); return 0; } diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index dd0873767ba..44dfa71b6f4 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -86,7 +86,7 @@ int video_reserve(ulong *addrp) return 0; } -void video_clear(struct udevice *dev) +int video_clear(struct udevice *dev) { struct video_priv *priv = dev_get_uclass_priv(dev); @@ -111,6 +111,8 @@ void video_clear(struct udevice *dev) memset(priv->fb, priv->colour_bg, priv->fb_size); break; } + + return 0; } void video_set_default_colors(struct video_priv *priv) @@ -128,7 +130,7 @@ void video_set_default_colors(struct video_priv *priv) } /* Flush video activity to the caches */ -void video_sync(struct udevice *vid) +void video_sync(struct udevice *vid, bool force) { /* * flush_dcache_range() is declared in common.h but it seems that some @@ -147,7 +149,7 @@ void video_sync(struct udevice *vid) struct video_priv *priv = dev_get_uclass_priv(vid); static ulong last_sync; - if (get_timer(last_sync) > 10) { + if (force || get_timer(last_sync) > 10) { sandbox_sdl_sync(priv->fb); last_sync = get_timer(0); } @@ -162,7 +164,7 @@ void video_sync_all(void) dev; uclass_find_next_device(&dev)) { if (device_active(dev)) - video_sync(dev); + video_sync(dev, true); } } diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c index aeff65648c1..1377e190817 100644 --- a/drivers/video/video_bmp.c +++ b/drivers/video/video_bmp.c @@ -345,7 +345,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, break; }; - video_sync(dev); + video_sync(dev, false); return 0; } |